如何删除指定开始日期和结束日期期间之外的列表的日期时间元素?

How can I remove datetime elements of a list outside of a specified startdate and enddate period?

我有一个名为 'date' 的日期时间对象列表,我正在尝试删除列表中开始日期和结束日期之外的元素。谁能帮助我了解如何正确执行此操作以及为什么我会收到此列表索引超出范围的错误?我觉得我很亲近!

我的代码:

startDate = datetime.strptime('1948-1-1',"%Y-%m-%d")
endDate = datetime.strptime('1950-2-1',"%Y-%m-%d")

for row in range(0,len(date)):
  if date[row] < startDate:
    del date[row]
  elif date[row] > endDate:
    del date[row]

我也试过下面的方法,它运行但不删除列表元素:

count = 0

for row in date:
  if row < startDate:
    del date[count]
  elif row > endDate:
    del date[count]
  count += 1

当您循环遍历列表并删除相同的列表时,该列表使其不在索引中。想想看,你正在循环 len(list) 但列表的长度与删除的某些条目的长度不同。

所以列表理解在这里会有所帮助,请注意我将 > 和 < 更改为其他方式以获得预期结果,请参见下面的示例:

from datetime import datetime
# datasetup
date=['1947-01-01','1948-01-01','1948-02-02','1951-01-01']
date=[datetime.strptime(each,"%Y-%m-%d") for each in date]
#Control date
startDate = datetime.strptime('1948-1-1',"%Y-%m-%d")
endDate = datetime.strptime('1950-2-1',"%Y-%m-%d")
#list comprehension
date = [each for each in date if  each >= startDate and each <= endDate ]

采取进一步的解决方案,从google 驱动器下载数据,使用pandas 过滤需要的数据,然后绘制以供分析。 第一步- 下载数据

import pandas as pd
import requests
from io import StringIO

gd_url='https://drive.google.com/file/d/1N2J136mog2CZK_XRyL3pxocaoUV8DByS/view?usp=sharing'
file_id = gd_url.split('/')[-2]
download_url='https://drive.google.com/uc?export=download&id=' + file_id
url = requests.get(download_url).text # get the file
csv_raw = StringIO(url)
df = pd.read_csv(csv_raw)
print(df.head(1))

步骤 2:筛选数据

#Control date
startDate = '1948-01-01'
endDate = '1950-02-01'
df_new=df.loc[(df['DATE'] >= startDate) & (df['DATE'] <= endDate)] # as doing string compare, make sure that 
#data looks okay otherwise change it to date for comparision

第 3 步:显示图表。

import pandas as pd
import matplotlib.pyplot as plt
df_new.plot()
plt.show() 

这是一个与您的问题相同的类似代码片段。

numbers = list(range(10))

for i in range(len(numbers)):
    if numbers[i] < 3:
        del numbers[i]
    elif numbers[i] > 7:
        del numbers[i]

这个问题是 range(len(numbers)) 是在循环开始时创建的,它没有注意到 numbers 的长度在迭代时发生了变化。

这可以通过 while 循环解决:

numbers = list(range(10))

i = 0
while i < len(numbers):
    if numbers[i] < 2:
        del numbers[i]
    elif numbers[i] > 7:
        del numbers[i]
    else:
        i += 1

print(numbers)

注意 i 只有在没有从列表中删除任何内容时才会递增,因为如果说索引 1 被删除,那么索引 2 中的项目将向左移动到填补空白,因此索引 1 需要再次检查。

然而,这个解决方案很冗长,不是很 Pythonic,而且效率很低(O(n^2) 复杂,因为从列表中删除一个项目是 O(n),它可以完成 n次)。 我建议您使用列表理解来过滤值,如下所示:

numbers = list(range(10))

print([number for number in numbers if 2 <= number <= 7])

或者,如果循环内需要更复杂的计算,您可以附加到新列表(总共 O(n) 复杂度):

numbers = list(range(10))
new_numbers = []
for i in range(len(numbers)):
    do_delete = False
    if numbers[i] < 2:
        do_delete =True
    elif numbers[i] > 7:
        do_delete = True

    if not do_delete:
        new_numbers.append(numbers[i])

print new_numbers

或者您可以使用生成器函数(也 O(n)):

numbers = list(range(10))

def my_filter(numbers):
    for i in range(len(numbers)):
        do_delete = False
        if numbers[i] < 2:
            do_delete = True
        elif numbers[i] > 7:
            do_delete = True

        if not do_delete:
            yield numbers[i]

print(list(my_filter(numbers)))

使用下面的示例代码

from datetime import datetime


startDate = datetime.strptime('1948-1-1',"%Y-%m-%d")
endDate = datetime.strptime('1950-2-1',"%Y-%m-%d")


date_list = []

date_list.append( datetime.strptime('1949-1-1',"%Y-%m-%d"))
date_list.append( datetime.strptime('1949-2-1',"%Y-%m-%d"))
date_list.append( datetime.strptime('1949-2-3',"%Y-%m-%d"))
date_list.append( datetime.strptime('1950-2-3',"%Y-%m-%d"))
date_list.append( datetime.strptime('1950-2-1',"%Y-%m-%d"))
date_list.append( datetime.strptime('1999-2-1',"%Y-%m-%d"))
date_list.append( datetime.strptime('1993-2-1',"%Y-%m-%d"))
date_list.append( datetime.strptime('1995-2-1',"%Y-%m-%d"))


new_list = copy.deep_copy(date_list)

for idx, date in enumerate(ll):
    if not date < startDate or not date > endDate:
        new_list.append(date)
        

print(new_list)