将日期范围拆分为多个范围

4

我有一些CSV格式的数据,像这样:

1940-10-01,somevalue
1940-11-02,somevalue
1940-11-03,somevalue
1940-11-04,somevalue
1940-12-05,somevalue
1940-12-06,somevalue
1941-01-07,somevalue
1941-02-08,somevalue
1941-03-09,somevalue
1941-05-01,somevalue
1941-06-02,somevalue
1941-07-03,somevalue
1941-10-04,somevalue
1941-12-05,somevalue
1941-12-06,somevalue
1942-01-07,somevalue
1942-02-08,somevalue
1942-03-09,somevalue

我希望将所有数据中的日期从1-oct-year31-march-next-year分离出来。因此,对于上面的数据,输出结果将为:

1940/1941:

1940-11-02,somevalue
1940-11-03,somevalue
1940-11-04,somevalue
1940-12-05,somevalue
1940-12-06,somevalue
1941-01-07,somevalue
1941-02-08,somevalue
1941-03-09,somevalue

1941/1942:

1941-10-04,somevalue
1941-12-05,somevalue
1941-12-06,somevalue
1942-01-07,somevalue
1942-02-08,somevalue
1942-03-09,somevalue
1942-10-01,somevalue

我的代码轨迹:

import csv
from datetime import datetime

with open('data.csv','r') as f:
    data = list(csv.reader(f))

quaters = []
year =  datetime.strptime(data[0][0], '%Y-%m-%d').year
for each in data:
    date =  datetime.strptime(each[0], '%Y-%m-%d')
    print(each)        

    if (date>=datetime(year=date.year,month=10,day=1) and date<=datetime(year=date.year+1,month=3,day=31)):
        middle_quaters[-1].append(each)
    if year != date.year:            
        quaters.append([])

但是我没有得到预期的输出。我希望将每个日期范围存储在单独的列表中。


你的样本结果有错误吗?为什么1941/42年的结果中有一条记录是1940年的?请看我的答案,其中包含正确的输出。 - Kaushal28
@Kaushal28,我刚刚注意到了,那是个打字错误。 - Ayyan Khan
3个回答

0

不使用外部包...根据所选字段创建查找表,然后将其转换为整数,并进行小于或大于的比较以确定范围。

import re

data = '''1940-10-01,somevalue
1940-11-02,somevalue
1940-11-03,somevalue
1940-11-04,somevalue
1940-12-05,somevalue
1940-12-06,somevalue
1941-01-07,somevalue
1941-02-08,somevalue
1941-03-09,somevalue
1941-05-01,somevalue
1941-06-02,somevalue
1941-07-03,somevalue
1941-10-04,somevalue
1941-12-05,somevalue
1941-12-06,somevalue
1942-01-07,somevalue
1942-02-08,somevalue
1942-03-09,somevalue'''

lookup={}
lines = data.split('\n')
for line in lines:
    d = re.sub(r'-','',line.split(',')[0])
    lookup[d]=line

dates=sorted(lookup.keys())

_in=19401201
out=19411004
outfile=[]
for date in dates:
    if int(date) > _in and int(date) < out:
        outfile.append(lookup[date])

for l in outfile:
    print outfile


输入是存储在文件中的吗?将CSV先转换为字符串,然后应用整数操作来确定日期时间范围并不是最优化的方法。 - Kaushal28

0

我会使用 pandas dataframe 来完成这个任务,这样会更容易。请参考以下链接:Pandas: Selecting DataFrame rows between two dates (Datetime Index)

对于你的情况:

data = pd.read_csv("data.csv")
df.loc[startDate : endDate]



# you can walk through a bunch of ranges like so..
listOfDateRanges = [(), (), ()]
for date_range in listOfDateRanges:
   df.loc[date_range[0] : date_range[1]]

但是我的日期范围会随时改变,可能在任何一年内,所以我不能硬编码它。 - Ayyan Khan
你在哪里硬编码数值? - Yatish Kadam
你的startDate和endDate可以是任何你想要的东西。将它们作为元组放入列表中,并遍历范围以获取所需的日期。 - Yatish Kadam
@Kaushal28 你的意思是什么?实际上你只是传递了一个过滤后的参数。 - Yatish Kadam

0
为了实现这个目的,你可以使用pandas库。以下是相同目的的示例代码:
import pandas as pd
df = pd.read_csv('so.csv', parse_dates=['timestamp'])   #timestamp is your time column
current_year, next_year = 1940, 1941
df = df.query(f'(timestamp >= "{current_year}-10-01") & (timestamp <= "{next_year}-03-31")')
print (df)

这将在您的数据上产生以下结果:

   timestamp      value
0 1940-10-01  somevalue
1 1940-11-02  somevalue
2 1940-11-03  somevalue
3 1940-11-04  somevalue
4 1940-12-05  somevalue
5 1940-12-06  somevalue
6 1941-01-07  somevalue
7 1941-02-08  somevalue
8 1941-03-09  somevalue

希望这能帮到你!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接