我想滚动窗口聚合一个数据框,但是我的结果必须保留具有唯一索引的列是至关重要的,因为稍后我想将聚合重新加入到原始数据框中。
就像
df = pd.DataFrame(
{"id": range(6),
"t": [pd.Timestamp("2019-01-01")+dt.timedelta(seconds=sec) for sec in [2, 2, 1, 1, 1, 1]],
"gr": list("ababab"),
"val": range(6)})
agg = df.groupby("gr").rolling("2s", on="t")["val"].sum() # <- id not present anymore
现在,我想将agg
加入df
上的id
中,但是不幸的是,熊猫rolling
使t
成为了多索引级别。 (时间t
实际上不是唯一的)
有什么办法可以在id
中获得agg
吗?
看着
>>> df.sort_values(["gr", "t"])
id t gr val
2 3 2019-01-01 00:00:01 a 2
4 1 2019-01-01 00:00:01 a 4
0 5 2019-01-01 00:00:02 a 0
3 2 2019-01-01 00:00:01 b 3
5 0 2019-01-01 00:00:01 b 5
1 4 2019-01-01 00:00:02 b 1
预期金额应为
id t gr sum_val
2 3 2019-01-01 00:00:01 a 2
4 1 2019-01-01 00:00:01 a 6
0 5 2019-01-01 00:00:02 a 6
3 2 2019-01-01 00:00:01 b 3
5 0 2019-01-01 00:00:01 b 8
1 4 2019-01-01 00:00:02 b 9
但是,一种建议的解决方案的输出是
agg = df.sort_values("t").groupby(['gr']).rolling("2s", on="t")['val'].sum().reset_index(name='sum_val')
agg['id'] = df.sort_values(['gr'])['id'].values
agg.sort_values(["gr", "t"])
输出:
gr t sum_val id
0 a 2019-01-01 00:00:01 2.0 5
1 a 2019-01-01 00:00:01 6.0 3
2 a 2019-01-01 00:00:02 6.0 1
3 b 2019-01-01 00:00:01 3.0 4
4 b 2019-01-01 00:00:01 8.0 2
5 b 2019-01-01 00:00:02 9.0 0
gr='a'
,id=5
应该是6?!
更新:我花了很多时间来演示这个问题。
更新:将t
设置为时间列,因为在它没有做应做的事情之前。
答案 0 :(得分:1)
由于t
在组中不是唯一的,但是id
是唯一的,并且您正在gr
上分组,因此您可以执行以下操作:
agg = df.groupby(['gr']).rolling(2, on="t")['val'].sum().reset_index(name='sum_val')
agg['id'] = df.sort_values(['gr'])['id'].values
输出:
gr t sum_val id
0 a 1 NaN 0
1 a 1 2.0 2
2 a 2 6.0 4
3 b 1 NaN 1
4 b 1 4.0 3
5 b 2 8.0 5
如果t
是唯一的,则可以执行以下操作:
您可以与原始df合并
df.groupby(['gr']).rolling(2, on="t")['val'].sum().reset_index(name='sum_val').merge(df[['id', 't', 'gr']])
输出:
gr t sum_val id
0 a 1 NaN 0
1 a 2 2.0 2
2 a 3 6.0 4
3 b 1 NaN 1
4 b 2 4.0 3
5 b 3 8.0 5
答案 1 :(得分:0)
您的意思是:
df['roll'] = (df.groupby("gr", as_index=False, group_keys=False)
.apply(lambda x: x.rolling(2, on='t')['val'].sum())
)
输出:
id t gr val roll
0 0 1 a 0 NaN
1 1 1 b 1 NaN
2 2 1 a 2 2.0
3 3 1 b 3 4.0
4 4 2 a 4 6.0
5 5 2 b 5 8.0