Python pandas - 在缺少日期的情况下按组有效地将函数应用于滚动窗口
Posted
技术标签:
【中文标题】Python pandas - 在缺少日期的情况下按组有效地将函数应用于滚动窗口【英文标题】:Python pandas - Efficiently apply function over rolling window by group with missing dates 【发布时间】:2020-06-30 09:38:15 【问题描述】:注意:我已经知道这个问题的答案,我发布它只是因为我找不到堆栈溢出的正确答案,而且我花了惊人的时间才弄清楚。话虽如此,请随时提出其他选择。
问题
我有一个包含三列的 pandas DataFrame,一列跟踪日期,一列跟踪相关观察结果(即我的分组列),第三个变量存储一些数值。对于我的数据框中的每个组,我想计算日期列的滚动总和。 警告:数据框中缺少某些日期,我想将它们视为值为 0 的观察值。我不想使用交叉连接来添加所有日期。
可重现的例子
让我们有一个这样的数据框:
df = pd.DataFrame('id_col' : np.array([1,1,1,1,1,1,2,2,2,2,2,3,3,3]),
'value_col' : np.random.randint(0,5,size=14),
'dates' : pd.to_datetime(np.array([
'2018-01-01',
'2018-02-01',
'2018-03-01',
'2018-05-01',
'2018-06-01',
'2018-09-01',
'2018-01-01',
'2018-02-01',
'2018-05-01',
'2018-06-01',
'2018-07-01',
'2018-01-01',
'2018-02-01',
'2018-03-01'])
)
)
数据看起来像这样:
id_col value_col dates
0 1 0 2018-01-01
1 1 1 2018-02-01
2 1 4 2018-03-01
3 1 0 2018-05-01
4 1 3 2018-06-01
5 1 3 2018-09-01
6 2 4 2018-01-01
7 2 3 2018-02-01
8 2 2 2018-05-01
9 2 0 2018-06-01
10 2 2 2018-07-01
11 3 4 2018-01-01
12 3 2 2018-02-01
13 3 3 2018-03-01
我尝试过但不起作用的方法:
选项 1: 完全忽略缺失的日期
df.groupby(['id_col']).rolling(2)['value_col'].sum().reset_index()
选项 2: 基于 pandas rolling documentation,使用 pandas 偏移参数(返回 ValueError: window must be an integer
)替换窗口宽度。如果将日期列用作数据框的索引,则此方法将起作用。不幸的是,我们不能在这里使用简单的索引,因为来自 id_col 的 2 个不同的 ID 可以包含相同的日期。 (我们可以创建 MultiIndex,但会得到相同的值错误)。
df.groupby(['id_col']).rolling('60d')['value_col'].sum().reset_index()
什么有效但不是很简单:
选项 1: 交叉联接以填写所有缺失的日期(如果您有大量数据可能会很困难)
选项 2: 从可迭代的笛卡尔积构建多索引,如 answer 所示。这实际上与上述选项非常相似。
【问题讨论】:
【参考方案1】:使用rolling
的on
参数。 documentation 实际上提到了它,尽管没有示例可以看到适当的用法。幸运的是,有 pandas github 和 this 问题,如果您通过 cmets,可以了解如何正确使用具有偏移窗口的滚动功能。
因此,解决方案是:
df.groupby(['id_col']).rolling('60d', on = 'dates')['value_col'].sum().reset_index()
注意 60d
的使用作为 2 个月的代理而不是 2m
这是因为 2m
会给您以下错误:ValueError: <2 * MonthEnds> is a non-fixed frequency
。有关此问题的更多信息,请查看 *** 问题here。
【讨论】:
以上是关于Python pandas - 在缺少日期的情况下按组有效地将函数应用于滚动窗口的主要内容,如果未能解决你的问题,请参考以下文章
在给定日期时间连续性的情况下,Pandas 输出日期、开始和结束时间以及事件状态
缺少日期的 Pandas Date MultiIndex - 滚动总和
如何在不使用 Pandas 的情况下创建等效于 numpy.nan 的日期时间对象?