编辑:我意识到时间窗口不是我想到的,所以下面的解决方案似乎确实有效:/
我想对变量val
和时间t
进行滚动窗口聚合,但每个窗口应该在分类变量cat
内。
我还想保留旧列,只是在它们旁边生成一个新的聚合列。
所以我试过
import random
import numpy as np
import pandas as pd
N=100
np.random.seed(0)
random.seed(0)
df = pd.DataFrame({"t": [pd.Timestamp(1514764800+random.randint(0, 10000000), unit="s") for _ in range(N)],
"cat": np.random.choice(["a", "b", "c"], size=N),
"val": np.random.randint(1,10, size=N),
})
df_agg = (df.groupby("cat", group_keys=False)
.apply(lambda d:d.assign(aggval=d.sort_values("t")
.rolling("7d", on="t")
["val"].agg("sum")
)
)
).sort_values(["cat", "t"])
-->
cat t val aggval
41 a 2018-01-01 05:19:33 5 5.0
38 a 2018-01-03 17:26:20 9 14.0
2 a 2018-01-08 20:40:15 6 15.0
36 a 2018-01-13 02:14:38 9 15.0
22 a 2018-01-15 07:39:52 1 16.0
89 a 2018-01-16 13:59:03 6 16.0
85 a 2018-01-18 10:36:42 9 25.0
...
但这似乎没有让订单正确。
这样做的正确方法是什么?
答案 0 :(得分:2)
可以使用此替代解决方案join
用于新列:
df_agg1 = (df.join(df.sort_values("t")
.set_index('t')
.groupby("cat")
.rolling("7d")["val"].sum()
.rename('aggval'), on=['cat','t'])
.sort_values(["cat", "t"]))
print (df_agg1.head(10))
cat t val aggval
41 a 2018-01-01 05:19:33 5 5.0
38 a 2018-01-03 17:26:20 9 14.0
2 a 2018-01-08 20:40:15 6 15.0
36 a 2018-01-13 02:14:38 9 15.0
22 a 2018-01-15 07:39:52 1 16.0
89 a 2018-01-16 13:59:03 6 16.0
85 a 2018-01-18 10:36:42 9 25.0
26 a 2018-01-20 13:18:05 4 20.0
15 a 2018-01-28 03:15:45 2 2.0
78 a 2018-02-05 16:53:25 6 6.0
print ((df_agg == df_agg1).all())
cat True
t True
val True
aggval True
dtype: bool
如果不需要新栏目:
df_agg = (df.sort_values("t")
.set_index('t')
.groupby("cat")
.rolling("7d")["val"].sum()
.reset_index()
)
print (df_agg.head(10))
cat t val
0 a 2018-01-01 05:19:33 5.0
1 a 2018-01-03 17:26:20 14.0
2 a 2018-01-08 20:40:15 15.0
3 a 2018-01-13 02:14:38 15.0
4 a 2018-01-15 07:39:52 16.0
5 a 2018-01-16 13:59:03 16.0
6 a 2018-01-18 10:36:42 25.0
7 a 2018-01-20 13:18:05 20.0
8 a 2018-01-28 03:15:45 2.0
9 a 2018-02-05 16:53:25 6.0