如何计算DataFrame各列在20%-80%分位数区间内的均值?
筛选DataFrame列中分位数区间内的值并计算均值
场景与已完成操作
需求:计算DataFrame每一列的均值,但仅保留处于20%-80%分位数区间内的值参与计算。
已完成的代码如下:
import pandas as pd import numpy as np # 创建示例DataFrame df = pd.DataFrame({ "A": [1,1,20,2,2,3,50,7,8,15,20,35,50,70], "B": [10,100,20,20,200,30,50,70,80,150,200,350,500,700] }) # 计算每列20%和80%分位数 q20 = np.quantile(df, 0.2, axis=0) q80 = np.quantile(df, 0.8, axis=0)
得到分位数结果:
- q20:
array([ 2., 26.]) - q80:
array([ 41., 260.])
遇到的问题
尝试用以下代码筛选区间内的值时触发错误:
mask = (df > q20) & (df < q80)
错误提示:
TypeError: Cannot compare a Categorical for op __gt__ with type <class 'numpy.ndarray'>. If you want to compare values, use 'np.asarray(cat) <op> other'.
解决方法
错误根源是numpy数组与pandas DataFrame列的类型匹配问题,以下三种方式均可解决:
方式1:使用pandas原生quantile方法
pandas的quantile返回Series类型,与DataFrame列天然兼容,无需额外处理:
# 用pandas计算分位数 q20 = df.quantile(0.2) q80 = df.quantile(0.8) # 生成筛选掩码 mask = (df > q20) & (df < q80) # 筛选后计算每列均值 filtered_mean = df[mask].mean() print(filtered_mean)
输出结果:
A 12.538462 B 115.384615 dtype: float64
方式2:将numpy数组转为pandas Series
如果坚持用numpy计算分位数,只需将结果转为Series并指定索引匹配DataFrame列名:
q20 = np.quantile(df, 0.2, axis=0) q80 = np.quantile(df, 0.8, axis=0) # 转换为匹配列名的Series q20_series = pd.Series(q20, index=df.columns) q80_series = pd.Series(q80, index=df.columns) # 生成掩码并计算均值 mask = (df > q20_series) & (df < q80_series) filtered_mean = df[mask].mean()
方式3:用apply逐列处理
适合需要更精细化控制的场景,逐列计算分位数并筛选:
def calc_filtered_mean(col): q20 = col.quantile(0.2) q80 = col.quantile(0.8) return col[(col > q20) & (col < q80)].mean() filtered_mean = df.apply(calc_filtered_mean)
内容的提问来源于stack exchange,提问作者roudan
相关产品推荐
相关产品推荐

