pandas 没有for循环的panda Dataframe 列的子集累积和?

798qvoo8  于 2022-12-09  发布在  其他
关注(0)|答案(2)|浏览(160)

这是我在Cumulative sum of a pandas dataframe column without for loop?中提出的上一个问题的后续问题。
现在,我有一个pandas Dataframe df,它最初有2列:ida。例如,类似于

df = {'id': [1, 1, 1, 0, 0, 4, 5, 5], 'a': [2.5, 3.5, 1.0, 1.0 2.0, 4.0, 2.3, 4.4]}

我想制作

df = {'id': [1, 1, 1, 0, 0, 4, 5, 5], 'a': [2.5, 3.5, 1.0, 1.0 2.0, 4.0, 2.3, 4.4], 'b': [0, 2.5, 6.0, 0.0, 1.0, 0.0, 0.0, 2.3]}

因此,它引入了一个新列b,其中包含每个唯一id的累积和。有没有快速的方法来实现这一点?
请注意,唯一的id将始终位于相邻的行中。

eit6fx6z

eit6fx6z1#

可以将GroupBy.applypandas.Series.shift一起使用:

df["b"] = (
            df.groupby("id", group_keys=False)["a"]
              .apply(lambda x: x.shift(fill_value=0).cumsum())
          )
#输出:
print(df)
   id    a    b
0   1  2.5  0.0
1   1  3.5  2.5
2   1  1.0  6.0
3   0  1.0  0.0
4   0  2.0  1.0
5   4  4.0  0.0
6   5  2.3  0.0
7   5  4.4  2.3
xu3bshqb

xu3bshqb2#

您可以使用groupby()执行此操作,但返回DataFrame而不是单个行:

df = pd.DataFrame({'id': [1, 1, 1, 0, 0, 4, 5, 5], 'a': [2.5, 3.5, 1.0, 1.0, 2.0, 4.0, 2.3, 4.4]})

def cumsum(df):
    df['b'] = df['a'].shift(1).cumsum().fillna(0)
    return df

df2 = df.groupby('id').apply(cumsum)

如果相邻的行中有相同的id,也可以尝试以下操作:

df['id_change'] = df['id'].diff().abs() > 0
df['cumsum'] = df['a'].shift(1).cumsum().fillna(0)
df['base'] = df['cumsum'].where(df['id_change'], np.nan).fillna(method='ffill').fillna(0)
df['b'] = df['cumsum'] - df['base']

我故意留下了所有的列,这样更容易看到发生了什么。

相关问题