1

我正在尝试使用带有 groupby 的窗口大小为 2 的熊猫滚动功能。除了我还希望窗口包含当前值和进行值之外,这将是非常标准的。

具体来说,给定

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]})

我尝试了 2 种策略,但都没有奏效。我第一次尝试

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.]})

我想这里有一个我不知道的明显解决方案。任何帮助表示赞赏!

4

2 回答 2

1

If assign numpy array instead Series it not aligned correctly, never do it for avoid this problems. Need remove first level of MultiIndex by Series.reset_index with drop=True and then change order by indexing:

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
于 2021-05-11T11:57:44.190 回答
1

Another method:

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
于 2021-05-11T12:03:22.897 回答