python - 基于时间的 .rolling() 因 group by 而失败

标签 python pandas group-by

这是来自 Pandas Issue #13966 的代码片段

dates = pd.date_range(start='2016-01-01 09:30:00', periods=20, freq='s')
df = pd.DataFrame({'A': [1] * 20 + [2] * 12 + [3] * 8,
                   'B': np.concatenate((dates, dates)),
                   'C': np.arange(40)})

失败:

df.groupby('A').rolling('4s', on='B').C.mean()
ValueError: B must be monotonic

根据上面链接的问题,这似乎是一个错误。有没有人有好的解决方法?

最佳答案

先将B设置为索引,以便对其使用Groupby.resample方法。

df.set_index('B', inplace=True)

Groupby A 并根据秒频率重新采样。由于resample不能直接与rolling一起使用,使用ffill(forward fillna with NaN limit as 0)。 现在通过将窗口大小指定为 4(因为 freq=4s)间隔来使用 rolling 函数,并沿 C 列取平均值,如下所示:

for _, grp in df.groupby('A'):
    print (grp.resample('s').ffill(limit=0).rolling(4)['C'].mean().head(10)) #Remove head() 

获得的结果输出:

B
2016-01-01 09:30:00    NaN
2016-01-01 09:30:01    NaN
2016-01-01 09:30:02    NaN
2016-01-01 09:30:03    1.5
2016-01-01 09:30:04    2.5
2016-01-01 09:30:05    3.5
2016-01-01 09:30:06    4.5
2016-01-01 09:30:07    5.5
2016-01-01 09:30:08    6.5
2016-01-01 09:30:09    7.5
Freq: S, Name: C, dtype: float64
B
2016-01-01 09:30:00     NaN
2016-01-01 09:30:01     NaN
2016-01-01 09:30:02     NaN
2016-01-01 09:30:03    21.5
2016-01-01 09:30:04    22.5
2016-01-01 09:30:05    23.5
2016-01-01 09:30:06    24.5
2016-01-01 09:30:07    25.5
2016-01-01 09:30:08    26.5
2016-01-01 09:30:09    27.5
Freq: S, Name: C, dtype: float64
B
2016-01-01 09:30:12     NaN
2016-01-01 09:30:13     NaN
2016-01-01 09:30:14     NaN
2016-01-01 09:30:15    33.5
2016-01-01 09:30:16    34.5
2016-01-01 09:30:17    35.5
2016-01-01 09:30:18    36.5
2016-01-01 09:30:19    37.5
Freq: S, Name: C, dtype: float64

TL;DR

使用groupby.apply作为一种解决方法,而不是在适本地设置索引之后:

# tested in version - 0.19.1
df.groupby('A').apply(lambda grp: grp.resample('s').ffill(limit=0).rolling(4)['C'].mean())

(或)

# Tested in OP's version - 0.19.0
df.groupby('A').apply(lambda grp: grp.resample('s').ffill().rolling(4)['C'].mean())

两者都有效。

关于python - 基于时间的 .rolling() 因 group by 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40821926/

相关文章:

python - 具有数据框两个键的字典

python - 匹配数字的正则表达式(正则和罗马)

python - Sumproduct 等效的 python 代码运行时间太长

python-2.7 - Python Pandas 'str' 对象不可调用

c# - 使用 LINQ 从单元格集合创建一个 int 列表

mysql - SQL统计高于和低于平均分的学生人数

python - 不使用模块,如何确定整数的宽度?

python - 一次获取多条 IMAP 消息

python - 是否可以根据列将 excel 文件拆分为切片?

MYSQL 获取特定表字段计数