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

如何动态筛选DataFrame中所有列值大于行平均值40%的行?

问题

现有一个包含ID列和数值列A、B、C的DataFrame,需要筛选出所有行中A、B、C的值均大于该行平均值40%的记录。示例DataFrame定义如下:

import pandas as pd

df = pd.DataFrame([['AA',10,8,12],['BB',10,2,18],['CC',10,6,14]],
                  columns=['ID','A', 'B', 'C'])
print(df)
# 输出:
#     ID  A   B   C
# 0   AA  10  8   12
# 1   BB  10  2   18
# 2   CC  10  6   14

具体逻辑:以每行A、B、C的平均值的40%作为阈值,若该行任意一列值低于该阈值则移除该行。例如第0行均值为10,阈值为4,所有列值均大于4;第1行B列值为2小于4,需移除;第2行所有列值均大于4。

尝试以下代码后得到空DataFrame:

df = df[(df[['A','B','C']] > (0.4*df[['A','B','C']].mean(axis=1))).all(1)]
print(df)
# 输出空表:
# ID  A   B   C

仅当硬编码阈值(如0.4*10)时代码有效:

df[(df[['A','B','C']] > 0.4*10).all(1)]

如何实现基于行平均值动态计算阈值的筛选?

解决方案

问题出在广播对齐上:df[['A','B','C']].mean(axis=1)返回的是行方向的Series(索引为行号,值为每行的均值*0.4),直接和3列的DataFrame比较时,Pandas会按列名对齐,导致每行的元素和错误的阈值比较,最终得到全False的布尔矩阵。

只需将阈值Series转换为列向量,就能让每行的每个元素与该行的阈值正确比较,有两种实现方式:

方法1:用[:, None]扩展维度

# 计算每行的阈值:均值*0.4,转为列向量
row_threshold = 0.4 * df[['A','B','C']].mean(axis=1)[:, None]
# 筛选所有列值大于阈值的行
filtered_df = df[(df[['A','B','C']] > row_threshold).all(axis=1)]
print(filtered_df)

方法2:用to_frame()转置

row_threshold = 0.4 * df[['A','B','C']].mean(axis=1).to_frame().T
filtered_df = df[(df[['A','B','C']] > row_threshold).all(axis=1)]
print(filtered_df)

输出结果

两种方法都会得到正确的筛选结果:

ID   A  B   C
0   AA  10  8  12
2   CC  10  6  14

原理说明

将行方向的Series转为列向量后,Pandas会自动广播为与原DataFrame相同的形状(3行3列),此时每行的A、B、C值会和该行对应的阈值逐一比较,生成正确的布尔矩阵,再通过.all(axis=1)判断该行所有列是否都满足条件,最终筛选出符合要求的行。

内容的提问来源于stack exchange,提问作者cph_sto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:12:08