如何让pct_change()的首个值不为NaN?求更高效实现方案
自定义首行基准的百分比变化计算优化方案
问题场景
给定以下DataFrame:
import pandas as pd df = pd.DataFrame( { 'a': [20, 30, 2, 5, 10] } )
需要生成pct_change列:
- 首行值通过
df.a.iloc[0]与固定值40对比计算 - 后续行使用常规的相邻行百分比变化逻辑
最终期望输出:
a pct_change 0 20 -50.000000 1 30 50.000000 2 2 -93.333333 3 5 150.000000 4 10 100.000000
常规df.a.pct_change().mul(100)会导致首行值为NaN,以下是几种更简洁高效的实现方式:
方法1:填充首行NaN(最简洁)
先计算常规的百分比变化,再直接替换首行的NaN值,无需自定义函数:
df['pct_change'] = df['a'].pct_change().mul(100) # 直接赋值首行的自定义计算结果 df['pct_change'].iloc[0] = ((df['a'].iloc[0] - 40) / 40) * 100
或者用fillna一次性完成填充:
first_pct = ((df['a'].iloc[0] - 40) / 40) * 100 df['pct_change'] = df['a'].pct_change().mul(100).fillna(first_pct)
方法2:构造完整基准序列(逻辑统一)
手动构造用于对比的基准序列:首元素为40,后续元素为a列的前一行值,直接整体计算所有行的百分比变化,避免单独处理首行:
# 构造基准序列:[40, 20, 30, 2, 5] base = pd.Series([40] + df['a'].tolist()[:-1], index=df.index) df['pct_change'] = ((df['a'] - base) / base) * 100
这种方式无需处理NaN,所有行的计算逻辑完全一致,代码可读性更强。
方法3:用shift生成对比序列(贴近pct_change本质)
pct_change的本质是(当前值/前值 - 1) * 100,我们可以用shift生成前值序列,再替换首行的前值为40:
prev_vals = df['a'].shift(1) prev_vals.iloc[0] = 40 df['pct_change'] = ((df['a'] / prev_vals) - 1) * 100
内容的提问来源于stack exchange,提问作者AmirX
相关产品推荐
相关产品推荐

