我有一个pandas数据框,用于存储日期范围和一些相关的列:
date_start date_end ... lots of other columns ...
1 2016-07-01 2016-07-02
2 2016-07-01 2016-07-03
3 2016-07-01 2016-07-04
4 2016-07-02 2016-07-07
5 2016-07-05 2016-07-06
另一个按日期索引的皮卡丘目击数据框:
pikachu_sightings
date
2016-07-01 2
2016-07-02 4
2016-07-03 6
2016-07-04 8
2016-07-05 10
2016-07-06 12
2016-07-07 14
对于第一个df中的每一行,我想计算该日期范围内的pikachu_sightings总和(即date_start
到date_end
)并将其存储在新列中。所以最终会得到这样的df(为了清晰起见留下数字):
date_start date_end total_pikachu_sightings
1 2016-07-01 2016-07-02 2 + 4
2 2016-07-01 2016-07-03 2 + 4 + 6
3 2016-07-01 2016-07-04 2 + 4 + 6 + 8
4 2016-07-02 2016-07-07 4 + 6 + 8 + 10 + 12 + 14
5 2016-07-05 2016-07-06 10 + 12
如果我是迭代地执行此操作,我会迭代日期范围表中的每一行,选择与日期范围匹配的目标表中的行子集并对其执行求和 - 但这是对我的数据集来说太慢了:
for range in ranges.itertuples():
sightings_in_range = sightings[(sightings.index >= range.date_start) & (sightings.index <= range.date_end)]
sum_sightings_in_range = sightings_in_range["pikachu_sightings"].sum()
ranges.set_value(range.Index, 'total_pikachu_sightings', sum_sightings_in_range)
这是我尝试使用pandas,但失败了,因为两个数据帧的长度不匹配(即使它们确实存在,我的方法可能还有一些其他缺陷):
range["total_pikachu_sightings"] =
sightings[(sightings.index >= range.date_start) & (sightings.index <= range.date_end)
["pikachu_sightings"].sum()
我试图了解一般方法/设计应该是什么样子,因为我也希望与其他功能聚合,sum
似乎是最简单的例子。对不起,如果这是一个显而易见的问题 - 我是熊猫新手!
答案 0 :(得分:2)
矢量化解决方案的草图:
在piRSquared的回答中以p
开头。
确保date_
cols有datetime64
个dtypes,即:
df['date_start'] = pd.to_datetime(df.date_time)
然后计算累积总和:
psums = p.cumsum()
和
result = psums.asof(df.date_end) - psums.asof(df.date_start)
但是,它还没有结束。 asof
会返回最后一个正常值,因此有时会采用确切的开始日期,有时则不会(取决于您的数据)。所以,你必须调整它。 (如果日期频率为day
,则可能会将p
的索引向后移动一小时,例如-pd.Timedelta(1, 'h')
,然后添加p.asof(df.start_date)
可能会有效。)
答案 1 :(得分:1)
首先确保pikachu_sightings
具有日期时间索引并已排序。
p = pikachu_sightings.squeeze() # force into a series
p.index = pd.to_datetime(p.index)
p = p.sort_index()
然后确保您的date_start
和date_end
为日期时间。
df.date_start = pd.to_datetime(df.date_start)
df.date_end = pd.to_datetime(df.date_end)
然后就是
df.apply(lambda x: p[x.date_start:x.date_end].sum(), axis=1)
0 6
1 12
2 20
3 54
4 22
dtype: int64