首页 > 解决方案 > 使用 groupby 计算未排序数据帧随时间变化的百分比

问题描述

我有一个df

    Name        Date ID  Amount
0   Faye  2019-12-31  A       2
1   Faye  2020-03-01  A       3
2   Faye  2019-09-30  A       1
3   Mike  2019-09-30  A       7
4   Mike  2019-12-31  A       7
5   Faye  2019-09-30  B      10
6   Mike  2019-12-31  B      12
7   Faye  2019-12-31  B       8
8   Faye  2019-06-30  B       5
9   Mike  2019-09-30  B      10
10  Faye  2019-09-30  C       5
11  Mike  2018-03-31  D       5

对于每个Name, Date, ID, 组,我想通过将其添加为新列 ( ) 来计算Amount前一个(如果有的话)的百分比变化。如果它以前不存在,请添加类似的内容,这样看起来像:Date% ChangeNewnew_df

    Name        Date ID  Amount % Change
0   Faye  2019-12-31  A       2        1
1   Faye  2020-03-01  A       3       .5
2   Faye  2019-09-30  A       1      New
3   Mike  2019-09-30  A       7      New
4   Mike  2019-12-31  A       7      NaN
5   Faye  2019-09-30  B      10       .5
6   Mike  2019-12-31  B      12       .2
7   Faye  2019-12-31  B       8      -.2
8   Faye  2019-06-30  B       5      New
9   Mike  2019-09-30  B      10      New
10  Faye  2019-09-30  C       5      New
11  Mike  2018-03-31  D       5      New

我试过df['% Change'] = (df.groupby(['Name', 'Date', 'ID'])['Amount'].apply(pd.Series.pct_change) + 1)了,但它返回了所有NaN. 也许这是因为数据没有排序?那么如何在没有排序数据框的情况下实现这一点呢?

标签: pythonpandas

解决方案


为什么不排序然后进行计算?那会奏效:

t = df.sort_values(["Name", "ID", "Date"])
t["change"] = t.Amount.pct_change()
t.loc[(t.shift()["Name"] != t.Name) |(t.shift()["ID"] != t.ID), "change"] = None
t

这将导致:(您可以忽略该inx列):

    inx Name    Date    ID  Amount  change
2   2   Faye    2019-09-30  A   1   NaN
0   0   Faye    2019-12-31  A   2   1.0
1   1   Faye    2020-03-01  A   3   0.5
8   8   Faye    2019-06-30  B   5   NaN
5   5   Faye    2019-09-30  B   10  1.0
7   7   Faye    2019-12-31  B   8   -0.2
10  10  Faye    2019-09-30  C   5   NaN
3   3   Mike    2019-09-30  A   7   NaN
4   4   Mike    2019-12-31  A   7   0.0
9   9   Mike    2019-09-30  B   10  NaN
6   6   Mike    2019-12-31  B   12  0.2
11  11  Mike    2018-03-31  D   5   NaN

推荐阅读