熊猫:按移动量和累计和

时间:2019-03-04 23:14:07

标签: python-3.x pandas pandas-groupby

我想做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

非常感谢。

3 个答案:

答案 0 :(得分:2)

您需要使用apply,因为一个功能位于groupby的{​​{1}} object下,而另一个cumsum的功能则适用于所有shift < / p>

df

答案 1 :(得分:2)

您可以使用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()的更多信息,请参见此处:

答案 2 :(得分:2)

在解决这个问题时,随着 DataFrame 大小的增长,在转换上使用 lambda 开始变得非常缓慢。我发现使用一些 DataFrameGroupBy 方法(例如 cumsumshift 而不是 lambdas 要快得多。

所以这是我建议的解决方案,创建一个 'temp' 列来保存每个 ID 的累积总和,然后转移到不同的 groupby:

df['temp'] = df.groupby("ID")['X'].cumsum()
df['transformed'] = df.groupby("ID")['temp'].shift()
df = df.drop(columns=["temp"])