Python 如何在滚动窗口聚合的同时保持索引列的唯一性?
我希望滚动窗口聚合一个数据帧,但我的结果保留一个具有唯一索引的列是至关重要的,因为稍后我希望将聚合重新加入到原始数据帧中 很像Python 如何在滚动窗口聚合的同时保持索引列的唯一性?,python,pandas,Python,Pandas,我希望滚动窗口聚合一个数据帧,但我的结果保留一个具有唯一索引的列是至关重要的,因为稍后我希望将聚合重新加入到原始数据帧中 很像 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 = 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
预期金额应为
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 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
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
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
gr='a'
,id=5
应该是6吗
更新:为了演示问题,我将时间重复了很多次。
更新:将
t
设置为时间列,因为之前它没有执行它应该执行的操作。由于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 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 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
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
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
如果t
是唯一的,则可以执行以下操作:
agg = df.groupby(['gr']).rolling(2, on="t")['val'].sum().reset_index(name='sum_val')
agg['id'] = df.sort_values(['gr'])['id'].values
您可以合并回原始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 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 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
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
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
你是说:
df['roll'] = (df.groupby("gr", as_index=False, group_keys=False)
.apply(lambda x: x.rolling(2, on='t')['val'].sum())
)
输出:
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 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
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
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
如何执行
agg.reset_index()
?由于将id
与其他id的滚动总和相关联看起来没有多大意义,因此您到底希望得到什么。我调整了示例,使时间在组内不唯一。这就是问题的根源。@QuangHoang我需要以某种方式将聚合回滚到原始数据帧中。这应该是一个有意义的行动?身份证只是为了找到正确的位置。哦,对了。但我意识到我的问题来自于时间的非唯一性,即使是在群体中。我调整了我的榜样。那我就不能再毫不含糊地加入了?!更新了我的答案@GerenukButb
以前有id 1,3,5,现在在第一个示例中有了3,4,5?@Gerenuk,忘记将id
作为数组。对于这个系列,它使用原始索引,这是错误的。修正了。(.values
)我意识到熊猫没有做我想做的事,也没有警告我。上的无效。如果我将t
更改为time,而将窗口更改为“2s”
则熊猫会在没有警告的情况下计算错误。但一旦您意识到这一点,并在t
上预排序,您的排序技巧就可以再次发挥作用。