groupby().quantile()可一行计算分组分位数,默认0.5,支持标量或列表输入;需注意非数值列被静默跳过、空组返回nan、插值方式影响结果,推荐一次性传入分位数列表提升性能。

用 groupby().quantile() 一行搞定分位数分组计算
直接调用 groupby().quantile() 是最简方式,它会自动对每组数值列返回指定分位数。默认计算 0.5(中位数),但你可以传入标量(如 0.9)或列表(如 [0.25, 0.5, 0.75])。
常见错误是传入字符串(如 "0.9")或没处理非数值列——Pandas 会静默跳过非数值列,不报错但结果可能少列,容易误以为计算失败。
-
df.groupby("category")["value"].quantile(0.9)→ 返回 Series,索引为(category, quantile)多级索引 -
df.groupby("category").quantile([0.25, 0.5, 0.75])→ 返回 DataFrame,列名带level_1后缀,需用.rename_axis(None, axis=1)清理 - 若想保留原始分组列名(如
"category")作为普通列而非索引,加as_index=False:df.groupby("category", as_index=False).quantile(0.9)
处理多级分组和混合数据类型
当按多个列分组(如 ["region", "year"])时,quantile() 输出的索引是 MultiIndex,直接取值易出错。更稳妥的做法是重置索引并扁平化列名。
同时注意:含字符串、时间戳等非数值列的 DataFrame 调用 .quantile() 时,Pandas 默认只对数值列生效,不会报错,但你可能根本没意识到某些列被忽略了。
- 显式指定目标列避免歧义:
df.groupby(["region", "year"])[["sales", "profit"]].quantile(0.9) - 列名含小数点或括号时(如
"p90_sales"),用.add_suffix("_p90")比手动重命名更安全 - 若某组数据全为 NaN 或空,
quantile()返回 NaN —— 这是预期行为,不是 bug,但需在后续逻辑中考虑缺失值处理
性能关键:大数组合下避免重复计算
多次调用 .quantile(0.1)、.quantile(0.5)、.quantile(0.9) 会触发三次分组扫描,对百万行以上数据明显变慢。一次性传入列表才是高效做法。
另外,quantile() 默认使用线性插值(interpolation="linear"),在整数索引或离散数据上可能产生非整数结果;若需四舍五入到最近观测值,改用 interpolation="nearest"。
- 快:
df.groupby("id").value.quantile([0.1, 0.5, 0.9]) - 慢(且冗余):
df.groupby("id").value.quantile(0.1)+ 单独再算 0.5 和 0.9 - 插值方式影响结果:比如 4 个数
[1,2,3,4]的 0.75 分位数,"linear"得3.25,"nearest"得3
替代方案:用 agg() 自定义更灵活的分位数逻辑
当需要组合分位数与其他统计量(如均值+P90),或对不同列用不同分位数时,agg() 更合适。它支持字典映射,还能混用函数与元组。
注意:传入 lambda 时别写成 lambda x: x.quantile(0.95) —— 这会丢失组内索引信息,推荐直接用 pd.Series.quantile 引用。
- 混合统计:
df.groupby("group").agg({"score": ["mean", pd.Series.quantile], "age": lambda x: x.quantile(0.95)}) - 指定不同分位数:
{"score": 0.9, "duration": 0.8}→ 会自动转为.quantile()调用 - 若自定义函数返回多个值(如上下四分位距),必须返回
pd.Series并设好index,否则列名会混乱
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











