Seaborn图表Y轴数值显示异常,疑与YOY计算相关
解决同比计算异常与Seaborn折线图Y轴显示问题
问题重现
我用以下代码创建了包含CPI、环比(mom)的DataFrame:
import pandas as pd import numpy as np import seaborn as sns date = pd.date_range('2003-01-01', '2022-11-01', freq='MS').strftime('%Y-%m-%d').tolist() mom = [np.nan] + list(np.repeat([0.01], 238)) cpi = [100] + list(np.repeat([np.nan], 238)) df = pd.DataFrame(list(zip(date, mom, cpi)), columns=['date','mom','cpi']) df['date'] = pd.to_datetime(df['date']) for i in range(1,len(df),1): df['cpi'][i] = df['cpi'][(i-1)] * (1 + df['mom'][i]) df['yoy'] = df['cpi'].pct_change(periods=12)
随后用Seaborn绘制同比(yoy)折线图时,Y轴数值显示异常:
sns.lineplot( x = 'date', y = 'yoy', data = df )
手动填充yoy列时绘图正常,推测问题出在pct_change的计算环节。
问题分析
- 链式索引赋值的隐患:循环中使用
df['cpi'][i]这种链式索引修改数据,可能导致Pandas无法正确跟踪数据类型,甚至引发SettingWithCopyWarning,最终导致cpi列的数据类型异常(比如变为object类型),进而干扰pct_change的计算结果。 - 循环计算的低效与风险:手动循环赋值容易出现索引错位,且无法保证数据的连续性和类型一致性。
解决方案
替换循环计算CPI的逻辑,使用Pandas的向量化操作cumprod高效计算累积增长,同时规避链式索引的问题:
import pandas as pd import numpy as np import seaborn as sns # 生成日期序列 date = pd.date_range('2003-01-01', '2022-11-01', freq='MS') # 构造mom列:第一个值为nan,后续均为0.01 mom = pd.Series([np.nan] + [0.01]*238, index=date) # 计算cpi:初始值100,基于(1+mom)的累积乘积计算 df = pd.DataFrame({'date': date, 'mom': mom}) df['cpi'] = 100 * (1 + df['mom']).fillna(1).cumprod() # 计算同比 df['yoy'] = df['cpi'].pct_change(periods=12) # 绘图验证 sns.lineplot(x='date', y='yoy', data=df)
效果说明
- 用
cumprod计算CPI是向量化操作,效率远高于手动循环,且能保证数据类型始终为数值型(float)。 fillna(1)处理了第一个mom的nan值,确保初始CPI保持100的基准值。- 计算出的yoy值会稳定在
(1.01**12)-1≈0.1268(即12.68%)左右,Seaborn绘图时Y轴会显示正常的百分比数值,不会出现异常。
内容的提问来源于stack exchange,提问作者youraz
相关产品推荐
相关产品推荐

