Pandas groupby 滚动获取未来值
Pandas groupby rolling for future values
我正在尝试将 pandas 滚动函数与 window 大小为 2 的 groupby 一起使用。这将是非常标准的,除此之外我还希望 window 包括当前值 和后续值。
具体来说,给定
df = pd.DataFrame({'groups':['a','a','a','a','a','b','b','b','b','b'],
'info': [i for i in range(10)]})
我要
pd.DataFrame({'groups':['a','a','a','a','a','b','b','b','b','b'],
'info': [i for i in range(10)],
'groupsum':[1, 3, 5, 7, nan, 11, 13, 15, 17, nan]})
我试过两种策略,都没有用。我第一次尝试
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=2)
df['groupsum'] = df.groupby('groups')['info'].rolling(window=indexer).mean().values
这种方式会导致内核崩溃,即使对于这个玩具数据框也是如此。很好奇为什么。
我的第二种方法是反转数据帧然后使用常规的 groupby 滚动操作:
df = df.iloc[::-1].copy()
df.index = range(df.shape[0])
df['groupsum'] = df.groupby('groups')['info'].rolling(2).sum().values
虽然内核不会用这种方法崩溃,但它不会产生我希望的数据帧;它产生
pd.DataFrame({'groups':['a','a','a','a','a','b','b','b','b','b'],
'info': [i for i in range(10)],
'groupsum':[nan, 7., 5., 3., 1., nan, 17., 15., 13., 11.]})
我想这里有一个我不知道的明显解决方案。感谢您的帮助!
如果分配给 numpy 数组而不是 Series 它没有正确对齐,切勿这样做以避免出现此问题。需要通过 Series.reset_index
和 drop=True
删除第一级 MultiIndex
,然后通过索引更改顺序:
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=2)
df['groupsum'] = df.groupby('groups')['info'].rolling(window=indexer).sum().reset_index(level=0, drop=True)
print (df)
groups info groupsum
0 a 0 1.0
1 a 1 3.0
2 a 2 5.0
3 a 3 7.0
4 a 4 NaN
5 b 5 11.0
6 b 6 13.0
7 b 7 15.0
8 b 8 17.0
9 b 9 NaN
df = df.iloc[::-1].copy()
df.index = range(df.shape[0])
df['groupsum'] = df.groupby('groups')['info'].rolling(2).sum().reset_index(level=0, drop=True)
df = df.iloc[::-1]
print (df)
groups info groupsum
9 a 0 1.0
8 a 1 3.0
7 a 2 5.0
6 a 3 7.0
5 a 4 NaN
4 b 5 11.0
3 b 6 13.0
2 b 7 15.0
1 b 8 17.0
0 b 9 NaN
另一种方法:
df["groupsum"] = df.groupby("groups")["info"].apply(lambda x: x + x.shift(-1))
>>> df
groups info groupsum
0 a 0 1.0
1 a 1 3.0
2 a 2 5.0
3 a 3 7.0
4 a 4 NaN
5 b 5 11.0
6 b 6 13.0
7 b 7 15.0
8 b 8 17.0
9 b 9 NaN
我正在尝试将 pandas 滚动函数与 window 大小为 2 的 groupby 一起使用。这将是非常标准的,除此之外我还希望 window 包括当前值 和后续值。
具体来说,给定
df = pd.DataFrame({'groups':['a','a','a','a','a','b','b','b','b','b'],
'info': [i for i in range(10)]})
我要
pd.DataFrame({'groups':['a','a','a','a','a','b','b','b','b','b'],
'info': [i for i in range(10)],
'groupsum':[1, 3, 5, 7, nan, 11, 13, 15, 17, nan]})
我试过两种策略,都没有用。我第一次尝试
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=2)
df['groupsum'] = df.groupby('groups')['info'].rolling(window=indexer).mean().values
这种方式会导致内核崩溃,即使对于这个玩具数据框也是如此。很好奇为什么。
我的第二种方法是反转数据帧然后使用常规的 groupby 滚动操作:
df = df.iloc[::-1].copy()
df.index = range(df.shape[0])
df['groupsum'] = df.groupby('groups')['info'].rolling(2).sum().values
虽然内核不会用这种方法崩溃,但它不会产生我希望的数据帧;它产生
pd.DataFrame({'groups':['a','a','a','a','a','b','b','b','b','b'],
'info': [i for i in range(10)],
'groupsum':[nan, 7., 5., 3., 1., nan, 17., 15., 13., 11.]})
我想这里有一个我不知道的明显解决方案。感谢您的帮助!
如果分配给 numpy 数组而不是 Series 它没有正确对齐,切勿这样做以避免出现此问题。需要通过 Series.reset_index
和 drop=True
删除第一级 MultiIndex
,然后通过索引更改顺序:
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=2)
df['groupsum'] = df.groupby('groups')['info'].rolling(window=indexer).sum().reset_index(level=0, drop=True)
print (df)
groups info groupsum
0 a 0 1.0
1 a 1 3.0
2 a 2 5.0
3 a 3 7.0
4 a 4 NaN
5 b 5 11.0
6 b 6 13.0
7 b 7 15.0
8 b 8 17.0
9 b 9 NaN
df = df.iloc[::-1].copy()
df.index = range(df.shape[0])
df['groupsum'] = df.groupby('groups')['info'].rolling(2).sum().reset_index(level=0, drop=True)
df = df.iloc[::-1]
print (df)
groups info groupsum
9 a 0 1.0
8 a 1 3.0
7 a 2 5.0
6 a 3 7.0
5 a 4 NaN
4 b 5 11.0
3 b 6 13.0
2 b 7 15.0
1 b 8 17.0
0 b 9 NaN
另一种方法:
df["groupsum"] = df.groupby("groups")["info"].apply(lambda x: x + x.shift(-1))
>>> df
groups info groupsum
0 a 0 1.0
1 a 1 3.0
2 a 2 5.0
3 a 3 7.0
4 a 4 NaN
5 b 5 11.0
6 b 6 13.0
7 b 7 15.0
8 b 8 17.0
9 b 9 NaN