pandas.Series.skew()和kurtosis()默认用无偏估计(ddof=1)计算偏度与超额峰度,自动跳过NaN,但要求数值型输入;scipy.stats对应函数默认有偏(bias=True),导致结果差异;describe()不包含偏度峰度,需单独调用。

用 pandas.Series.skew() 和 pandas.Series.kurtosis() 直接算
偏度(Skewness)衡量分布左右不对称程度,峰度(Kurtosis)反映尾部厚重程度(注意:pandas 默认计算的是 excess kurtosis,即减去正态分布的 3)。直接调用这两个方法最省事,但得确认数据类型和缺失值处理方式。
实操建议:
-
skew()和kurtosis()默认跳过NaN,无需提前dropna(),但若想强制包含缺失值,需先用fillna()处理 - 输入必须是数值型
Series或DataFrame的单列;若列含字符串或混合类型,会静默返回NaN,建议先检查dtype - 对
DataFrame调用时,会按列分别计算,返回Series,不支持跨行(axis=1)计算偏度/峰度
为什么 scipy.stats.skew() 和 pandas 结果有时不一致
根本区别在「无偏估计」和「样本 vs 总体」的默认设定。pandas 的 skew() 和 kurtosis() 默认使用无偏估计(即除以 n-1 的修正),而 scipy.stats.skew() 默认是 biased(除以 n),且 scipy 的 kurtosis() 默认也返回 excess 峰度,但可通过 fisher=False 切换为原始峰度(未减 3)。
常见错误现象:
立即学习“Python免费学习笔记(深入)”;
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 用
scipy.stats.kurtosis(x) == pandas.Series(x).kurtosis()返回False—— 实际上两者默认都是 excess 峰度,但scipy默认biased=True,pandas 默认ddof=1,导致数值微差 - 想复现 SPSS 或 Excel 的结果,需统一设
scipy.stats.skew(x, bias=True)和pandas.Series(x).skew(0)(0表示ddof=0)
在 describe() 中默认不显示偏度与峰度
DataFrame.describe() 默认只输出 count、mean、std、min、25%、50%、75%、max 这些统计量,偏度和峰度不在其中。不能靠加参数让它出现,必须单独调用。
使用场景:
- 快速探索性分析时,别指望
describe(include='number')自动带出偏度——它不会 - 若想批量计算多列的偏度/峰度并拼进描述表,可构造字典再转
DataFrame:pd.DataFrame({ 'skew': df.select_dtypes('number').apply(pd.Series.skew), 'kurtosis': df.select_dtypes('number').apply(pd.Series.kurtosis) }) - 注意
describe()对非数值列(如object类型)会跳过,但skew()遇到非数值列会直接报TypeError,不是静默跳过
空值、极少量数据或常数列会导致什么问题
这三个边界情况最容易被忽略,但一跑就报错或返回意外值。
容易踩的坑:
- 空
Series(len(s) == 0)调用skew()返回NaN,但不报错;而长度为 1 的序列,skew()也返回NaN(方差为 0,无法归一化) - 全相同值的列(如全是
5.0),skew()返回0.0(合理),但kurtosis()返回NaN(分母为 0) - 含大量
NaN的列(比如有效样本 skew() 仍可能返回数值,但标准误极大,实际不可信;pandas 不做样本量警告,得自己加判断:if s.count()
boxplot 看分布形态——否则 kurtosis = -1.2 可能只是小样本抖动,未必真代表扁平分布。

















