推荐使用 np.percentile 计算四分位数,需显式指定 nan_policy='omit' 处理缺失值,并确保有效样本量≥20;其结果与 Excel PERCENTILE.INC 和 Pandas 新版 quantile 一致。

直接用 np.percentile 算四分位数,别碰 np.quantile 或手动排序
NumPy 中最稳、最常用、文档最清晰的四分位数计算方式就是 np.percentile。它默认使用线性插值,和 Excel、Pandas(describe())、大多数金融分析工具对齐;而 np.quantile 虽然语义更“统计”,但参数名和默认行为容易混淆(比如 method 参数在旧版本不支持),实操中反而容易出错。
对金融时间序列(比如日收益率数组 rets),直接传入百分位点即可:
import numpy as np rets = np.array([0.012, -0.005, 0.021, -0.013, 0.008, 0.017, -0.009]) q1, q2, q3 = np.percentile(rets, [25, 50, 75])
结果 q1 ≈ -0.009、q2 = 0.008、q3 ≈ 0.017 —— 和你用 Excel 的 PERCENTILE.INC 一致。
处理含 NaN 的金融数据时,必须加 nan_policy='omit'
真实金融序列常有缺失(如停牌、接口异常),np.percentile 默认遇到 NaN 就直接返回 nan,不是报错,而是静默污染结果。这点极易被忽略,尤其当你后续做箱线图或异常值过滤时,整个逻辑就崩了。
立即学习“Python免费学习笔记(深入)”;
- 不加参数:只要
rets里有一个np.nan,np.percentile(rets, 25)就返回nan - 正确做法:显式写
np.percentile(rets, 25, nan_policy='omit') - 注意:
nan_policy='propagate'(默认)和'raise'都不适合生产场景;'omit'是唯一合理选择
示例:
rets_with_nan = np.array([0.012, np.nan, -0.005, 0.021]) print(np.percentile(rets_with_nan, 25)) # nan → 错误! print(np.percentile(rets_with_nan, 25, nan_policy='omit')) # -0.005 → 正确
四分位距(IQR)不能只算 q3 - q1,得先确认数据量是否足够
IQR 是风控和异常检测的关键指标,但它的可靠性高度依赖样本量。金融日频数据若只取 5 天,算出来的 IQR 没意义;月频若只给 3 个月,也基本不可信。
- 建议阈值:至少 20 个非 NaN 观测值再计算 IQR
- 检查方式:
valid_count = np.count_nonzero(~np.isnan(rets)) - 若
valid_count < 20,应跳过 IQR 计算,或打 warning,而不是硬算一个数字糊弄自己
完整稳健写法:
if np.count_nonzero(~np.isnan(rets)) >= 20:
q1 = np.percentile(rets, 25, nan_policy='omit')
q3 = np.percentile(rets, 75, nan_policy='omit')
iqr = q3 - q1
else:
iqr = np.nan # 或 raise ValueError("Insufficient data for IQR")和 Pandas 对齐时,注意 interpolation 参数已弃用,改用 method
如果你从 Pandas 的 Series.quantile(0.25) 切换到 NumPy,早期版本 Pandas 用 interpolation='linear',新版本(1.5+)已改为 method='linear',而 np.percentile 的底层逻辑和 Pandas 新版完全一致 —— 所以无需额外调整。
但要注意一个坑:Pandas 默认会自动 drop NaN,而 NumPy 不会,所以等价写法一定是:
- Pandas:
ser.quantile(0.25, method='linear') - NumPy:
np.percentile(ser.dropna(), 25)或np.percentile(ser, 25, nan_policy='omit')
漏掉 nan_policy='omit' 或忘了 dropna(),数值就会差一截,尤其在小样本+高缺失率时。
四分位数本身很简单,难的是在金融数据的脏、稀、断、异步场景下,让每个 np.percentile 调用都可复现、可解释、不静默失败。重点盯住 NaN 处理、样本量底线、和上下游工具的参数对齐 —— 其他都是次要的。


















