Pandas:按组位移和累积求和

11

我想做groupbyshiftcumsum,这似乎是一个非常简单的任务,但我对结果感到困惑。有人可以告诉我我错在哪里吗?我在网上找到的所有结果都显示与我所做的相同或相同变体。以下是我的实现。

temp = pd.DataFrame(data=[['a',1],['a',1],['a',1],['b',1],['b',1],['b',1],['c',1],['c',1]], columns=['ID','X'])

temp['transformed'] = temp.groupby('ID')['X'].cumsum().shift()
print(temp)

   ID   X   transformed
0   a   1   NaN
1   a   1   1.0
2   a   1   2.0
3   b   1   3.0
4   b   1   1.0
5   b   1   2.0
6   c   1   3.0
7   c   1   1.0
这是错误的,因为实际或者我要找的是以下内容:
   ID   X   transformed
0   a   1   NaN
1   a   1   1.0
2   a   1   2.0
3   b   1   NaN
4   b   1   1.0
5   b   1   2.0
6   c   1   NaN
7   c   1   1.0

非常感谢您的提前帮助。


temp2 = temp.groupby('ID').shift() temp2['ID'] = temp['ID'] temp2.groupby('ID').cumsum()虽然这只是一个快速而简单的解决方案,但我更喜欢 Wen-Bens 的答案。 - DatenBergwerker
3个回答

9
您可以使用transform()将在每个groupby级别创建的单独组馈送到cumsum()shift()方法中。
temp['transformed'] = \
    temp.groupby('ID')['X'].transform(lambda x: x.cumsum().shift())
  ID  X   transformed
0  a  1   NaN
1  a  1   1.0
2  a  1   2.0
3  b  1   NaN
4  b  1   1.0
5  b  1   2.0
6  c  1   NaN
7  c  1   1.0

关于transform()的更多信息,请参见以下链接:


感谢您的帮助和提供更好地理解转换工作原理的链接。 - Krishnang K Dalal

4
在解决这个问题时,随着DataFrame大小的增加,在transform上使用lambda会变得非常缓慢。我发现,与lambda相比,使用一些DataFrameGroupBy方法(如cumsumshift)要快得多。
因此,这是我的建议解决方案:创建一个'temp'列来保存每个ID的cumsum,然后在不同的groupby中进行移位操作。
df['temp'] = df.groupby("ID")['X'].cumsum()
df['transformed'] = df.groupby("ID")['temp'].shift()
df = df.drop(columns=["temp"])

我同意你的观点。是的,这是一个很酷的技巧。 - Krishnang K Dalal

4

你需要使用 apply 函数,因为其中一个函数位于 groupby 对象下,即 cumsum,另一个函数 shift 是针对所有 df 的。

temp['transformed'] = temp.groupby('ID')['X'].apply(lambda x  : x.cumsum().shift())
temp
Out[287]: 
  ID  X  transformed
0  a  1          NaN
1  a  1          1.0
2  a  1          2.0
3  b  1          NaN
4  b  1          1.0
5  b  1          2.0
6  c  1          NaN
7  c  1          1.0

感谢您的帮助和解释。 - Krishnang K Dalal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接