如何在Pandas DataFrame中批量计算当前行与前N行的百分比变化?
实现当前行与前N行逐行百分比变化的方法
好问题!Pandas里并没有直接实现这个特定需求的内置方法,但我们可以用移位(shift)操作快速写出代码来实现,逻辑其实很清晰,我给你演示一下。
先明确你的需求:对于每一行,生成N列,分别对应当前行与前1行、前2行…前N行的百分比变化(公式是1 - 前k行值/当前行值),前N行因为没有足够的历史数据,这些列都显示NaN,从第N+1行开始填充数值。
示例代码实现
我们先构造一个符合你描述的示例数据集,然后以N=4为例写出代码:
import pandas as pd # 构造示例数据,和你提到的例子对应 df = pd.DataFrame({'Data': [100, 103, 104, 106, 110, 112, 115]}) N = 4 # 生成列名:A、B、C、D col_names = [chr(ord('A') + i) for i in range(N)] # 循环生成每一列的百分比变化 for offset, col in zip(range(1, N+1), col_names): # shift(offset) 将数据向下偏移offset行,正好对应前offset行的值 df[col] = 1 - df['Data'].shift(offset) / df['Data']
执行这段代码后,你会得到这样的结果:
| Data | A | B | C | D | |
|---|---|---|---|---|---|
| 0 | 100 | NaN | NaN | NaN | NaN |
| 1 | 103 | NaN | NaN | NaN | NaN |
| 2 | 104 | NaN | NaN | NaN | NaN |
| 3 | 106 | NaN | NaN | NaN | NaN |
| 4 | 110 | 0.0364 | 0.0545 | 0.0636 | 0.0909 |
| 5 | 112 | 0.0536 | 0.0714 | 0.0804 | 0.1071 |
| 6 | 115 | 0.0261 | 0.0435 | 0.0957 | 0.1304 |
完全符合你要求的计算结果!
优化写法(无循环)
如果你的数据集很大,想避免循环,也可以用pd.concat结合列表推导式来实现:
col_names = [chr(ord('A') + i) for i in range(N)] # 生成所有需要的列,再和原DataFrame合并 df = pd.concat( [df] + [1 - df['Data'].shift(k)/df['Data'] for k in range(1, N+1)], axis=1 ) # 重新设置列名 df.columns = ['Data'] + col_names
公式调整说明
如果之后你需要的是常规的百分比变化((当前值-前k行值)/前k行值,也就是pct_change的计算逻辑),只需要把公式改成:
df[col] = (df['Data'] - df['Data'].shift(offset)) / df['Data'].shift(offset)
内容的提问来源于stack exchange,提问作者Ishwar Jindal




