You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:25:10