首页 > 解决方案 > 取行日期之前的值的总和

问题描述

我有一个看起来像这样的数据框:


df = pd.DataFrame({'id': {0: 1, 1: 3, 2: 2, 3: 2, 4: 1, 5: 3},
 'date': {0: '11/11/2018',
  1: '11/12/2018',
  2: '11/13/2018',
  3: '11/14/2018',
  4: '11/15/2018',
  5: '11/16/2018'},
 'score': {0: 1, 1: 1, 2: 3, 3: 2, 4: 0, 5: 5}})

我需要生成的数据框如下所示:

output = pd.DataFrame({'id': {0: 1, 1: 3, 2: 2, 3: 2, 4: 1, 5: 3},
 'date': {0: '11/11/2018',
  1: '11/12/2018',
  2: '11/13/2018',
  3: '11/14/2018',
  4: '11/15/2018',
  5: '11/16/2018'},
 'score': {0: 1, 1: 1, 2: 3, 3: 2, 4: 0, 5: 5},
 'total_score_per_id_before_date': {0: 1, 1: 1, 2: 3, 3: 3, 4: 1, 5: 1}})

到目前为止我的代码:

output= df[["id","score"]].groupby("id").sum()

但是,这给了我每个 id 的总分数。我需要该特定行中日期之前的分数总和。只有第一个分数不应该被丢弃。

标签: pythonpandasdataframedatetime

解决方案


在系列上使用累积和。然后减去当前值,因为您要求当前索引之前的累积总和。最后,加回第一个值,否则它们为零。

previously_accumulated_scores = df.groupby("id").cumsum().score - df.score

firsts = df.groupby("id").first().reset_index()
df2 = df.merge(firsts, on=["id", "date"], how="left", suffixes=("", "_r"))

df["total_score_per_id_before_date"] = previously_accumulated_scores + df2.score_r.fillna(0)

通过将索引更改为 MultiIndex,可以更优雅地完成合并,但这是一种风格偏好。

注意:这假设您的 DataFrame 按类似日期的列进行排序(groupby保留每个组中的行顺序(来源:docs))。


推荐阅读