Python 使用每年唯一的日期范围在dataframe中创建一个新列
我有一个如下形式的数据框:Python 使用每年唯一的日期范围在dataframe中创建一个新列,python,pandas,date,pandas-groupby,Python,Pandas,Date,Pandas Groupby,我有一个如下形式的数据框: df = pd.DataFrame({'Date':['2017-01-01', '2017-02-13', '2018-03-01', '2018-04-01'], 'Value':[1,2,3,4]}) 每年我都有一个不同的日期范围(例如2017年从2017年2月2日到2017年2月15日,2018年从2018年3月3日到2018年4月4日)作为字典存储 dates_dict = {2017: ('2017-02-02', '2017-02-15'), 2018
df = pd.DataFrame({'Date':['2017-01-01', '2017-02-13', '2018-03-01', '2018-04-01'], 'Value':[1,2,3,4]})
每年我都有一个不同的日期范围(例如2017年从2017年2月2日到2017年2月15日,2018年从2018年3月3日到2018年4月4日)作为字典存储
dates_dict = {2017: ('2017-02-02', '2017-02-15'), 2018: ('2018-03-03', '2018-04-04')}
我想在我的数据框中创建一个新列,如果日期在该日期范围内,则为True,否则为False。对于给定的示例,输出为:
df = Date Value in_range
0 2017-01-01 1 False
1 2017-02-13 2 True
2 2018-03-01 3 False
3 2018-04-01 4 True
我目前的解决办法是:
temp = []
for name, group in df.groupby(df['Date'].dt.year):
temp.append((group['Date'] >= dates_dict[name][0]) & (group['Date'] <=
dates_dict[name][1]))
in_range = pd.concat(temp)
in_range = in_range.rename('in_range')
df = df.merge(in_range.to_frame(), left_index=True, right_index=True)
temp=[]
对于名称,df.groupby中的组(df['Date'].dt.year):
临时追加((组['Date']>=日期[名称][0])和(组['Date']]设置
通过将词典转换为实际包含pd.date\u范围
,您可以提高解决方案的效率。这两种解决方案都假设您进行了此转换:
dates_dict = {k: pd.date_range(s, e) for k, (s, e) in dates_dict.items()}
选项1
通过字典查找使用应用
:
df.Date.apply(lambda x: x in dates_dict[x.year], 1)
0 False
1 True
2 False
3 True
Name: Date, dtype: bool
选项2
使用列表理解的性能稍高的选项:
df['in_range'] = [i in dates_dict[i.year] for i in df.Date]
Date Value in_range
0 2017-01-01 1 False
1 2017-02-13 2 True
2 2018-03-01 3 False
3 2018-04-01 4 True
计时
您可以使用map
为每个日期使用字典中的值创建序列ser
,然后在之间使用,例如:
ser = df.Date.dt.year.map(dates_dict)
df['in_range'] = df.Date.between(pd.to_datetime(ser.str[0]), pd.to_datetime(ser.str[1]))
你会得到:
Date Value in_range
0 2017-01-01 1 False
1 2017-02-13 2 True
2 2018-03-01 3 False
3 2018-04-01 4 True
多亏了这一点,我还没有看这方面的性能,但是你认为有矢量化的实现吗?我想知道,如果我有一个开始-结束元组的列表,然后逐步完成,然后做一个矢量化比较,或者将所有创建的系列合并为一个,我想你会得到一个矢量化的解决方案n通过更改跟踪日期范围的方式。我将公布列表理解和应用之间的性能差异,列表理解相当快。
Date Value in_range
0 2017-01-01 1 False
1 2017-02-13 2 True
2 2018-03-01 3 False
3 2018-04-01 4 True