计算 Pandas 数据框中列值之间的百分比变化

Calculate percentage change between values of column in Pandas dataframe

我有一个数据框,其中包含从 2017 年到 2021 年这 5 年的一些价格指数。它看起来像这样:

Country Industry Year Index
US Agriculture 2017 83
US Agriculture 2018 97.2
US Agriculture 2019 100
US Agriculture 2020 112
US Agriculture 2021 108
Japan Mining 2017 88
Japan Mining 2018 93
Japan Mining 2019 100
Japan Mining 2020 104
Japan Mining 2021 112

我的基准年是 2019 年,因此标记为 2019 的每一行的索引都是 100。其他所有内容都向上或向下移动。我想生成另一个名为 Percentage_Change 的列,显示从 2019 年作为基准年开始的同比变化。

我尝试使用 pd.series.pct_change 函数,但是,该函数计算从 2017 年开始的同比百分比变化,并为年份为 2017 的所有行生成一个 NaN 值,而不是2019年应该是基准年。

我希望输出如下所示:

Country Industry Year Index Percentage_change
Japan Mining 2017 88 -5.37%
Japan Mining 2018 93 -7%
Japan Mining 2019 100 0
Japan Mining 2020 104 4%
Japan Mining 2021 112 7.69%

日本 2021 年和 2020 年的 percentage_change 是 (112-104)/104 = 7.69%,2020 年和 2019 年的差异是 (104-100)/100 = 4%,两者之间的差异2018年和2019年是(93-100)/100 = -7%,2017年和2018年相差是(88-93)/93 = -5.37%

还有其他方法可以计算 pandas 的百分比变化吗?

pct_change 正在计算 相对于先前值 的变化(这就是 2017 年为 NaN 的原因),这似乎不是您想要的。如果您想计算相对于 2019 的百分比变化,因为 2019 已经归一化为 100,只需减去 100:

df['Percentage_Change'] = df['Index'].sub(100)

输出:

  Country     Industry  Year  Index  Percentage_Change
0      US  Agriculture  2017   83.0              -17.0
1      US  Agriculture  2018   97.2               -2.8
2      US  Agriculture  2019  100.0                0.0
3      US  Agriculture  2020  112.0               12.0
4      US  Agriculture  2021  108.0                8.0
5   Japan       Mining  2017   88.0              -12.0
6   Japan       Mining  2018   93.0               -7.0
7   Japan       Mining  2019  100.0                0.0
8   Japan       Mining  2020  104.0                4.0
9   Japan       Mining  2021  112.0               12.0

双向pct_change

如果您想要双向 pct_change“以 100 为中心”,您可以使用掩码来计算 pct_change 两种方式:

df['Percentage_Change'] = (df
 .assign(ref=df['Year'].eq(2019))
 .groupby(['Country', 'Industry'], group_keys=False)
 .apply(lambda g: g['Index'].where(g['ref'].cummax()).pct_change()
                  .fillna(g['Index'][::-1].pct_change().mask(g['ref'].cummax(), 0))
       )
)

输出:

  Country     Industry  Year  Index  Percentage_Change
0      US  Agriculture  2017   83.0          -0.146091
1      US  Agriculture  2018   97.2          -0.028000
2      US  Agriculture  2019  100.0           0.000000
3      US  Agriculture  2020  112.0           0.120000
4      US  Agriculture  2021  108.0          -0.035714
5   Japan       Mining  2017   88.0          -0.053763
6   Japan       Mining  2018   93.0          -0.070000
7   Japan       Mining  2019  100.0           0.000000
8   Japan       Mining  2020  104.0           0.040000
9   Japan       Mining  2021  112.0           0.076923