首页 > 解决方案 > 以另一列中的值为条件从一列运行总和

问题描述

我有一个包含与时间相关的数据值(在其他类别中)的数据集,我想添加一个累积值列 - 即所有值的总和,包括时间。所以,采取这样的事情:

   ID  YEAR  VALUE
0   A  2018    144
1   B  2018    147
2   C  2018    164
3   D  2018    167
4   A  2019    167
5   B  2019    109
6   C  2019    183
7   D  2019    121
8   A  2020    136
9   B  2020    187
10  C  2020    170
11  D  2020    188

并添加这样的列:

   ID  YEAR  VALUE  CUMULATIVE_VALUE
0   A  2018    144               144
1   B  2018    147               147
2   C  2018    164               164
3   D  2018    167               167
4   A  2019    167               311
5   B  2019    109               256
6   C  2019    183               347
7   D  2019    121               288
8   A  2020    136               447
9   B  2020    187               443
10  C  2020    170               517
11  D  2020    188               476

例如,在第 7 行中,CUMULATIVE_VALUE 是 2018 年和 2019 年(而不是2020 年)中 ID="D" 的 2 VALUE 的总和。

我已经看过cumsum()但看不到在这种特定情况下如何使用它,所以我想出的最好的方法是:

import numpy as np
import pandas as pd

np.random.seed(0)

ids=["A","B","C","D"]
years=[2018,2019,2020]

df = pd.DataFrame({"ID": np.tile(ids, 3), 
                   "YEAR": np.repeat(years, 4), 
                   "VALUE": np.random.randint(100,200,12)})
print(df)

df["CUMULATIVE_VALUE"] = None 
for id in ids:
  for year in years:
    df.loc[(df.ID==id) & (df.YEAR==year), "CUMULATIVE_VALUE"] = \
  df[(df.ID==id) & (df.YEAR <= year)].VALUE.sum()
print(df)

但我确信必须有更好、更有效的方法来做到这一点。任何人?

标签: python-3.xpandas

解决方案


You can use pd.Groupby to group by ID and aggregate with cumsum:

df['CUMULATIVE_VALUE'] = df('ID').VALUE.cumsum()

 ID  YEAR  VALUE  CUMULATIVE_VALUE
0   A  2018    144               144
1   B  2018    147               147
2   C  2018    164               164
3   D  2018    167               167
4   A  2019    167               311
5   B  2019    109               256
6   C  2019    183               347
7   D  2019    121               288
8   A  2020    136               447
9   B  2020    187               443
10  C  2020    170               517
11  D  2020    188               476

In the case the years are not sorted instead do:

df = df.sort_values(['ID','YEAR']).reset_index(drop=True)
df['cumsum'] = df.groupby('ID').agg({'VALUE':'cumsum'})

推荐阅读