基于分位数阈值删异常值:两段Pandas代码为何效果不同?
分位数法删除异常值:两段代码的差异解析
你用分位数定义了异常值阈值:
low = df[columns].quantile(0.003) high = df[columns].quantile(0.997)
第一段代码无效的原因
第一段代码的逻辑完全不符合异常值删除的需求:
df = df[(df[columns]>low).any(axis=1)] df = df[(df[columns]<high).any(axis=1)]
(df[columns]>low).any(axis=1):只要某一行任意一列大于对应列的low阈值,就保留该行。由于low是0.003分位数,只有极个别行的所有列都低于low,所以这一步几乎不会删除任何数据。(df[columns]<high).any(axis=1):同理,只要某一行任意一列小于对应列的high阈值,就保留该行。正常数据里几乎所有行都满足这个条件,所以第二次过滤后数据依然没有变化。
第二段代码有效的原因
第二段代码才是正确的异常值过滤逻辑:
df = df[~(df[columns]<low).any(axis=1)] df = df[~(df[columns]>high).any(axis=1)]
~(df[columns]<low).any(axis=1):(df[columns]<low).any(axis=1)会标记出“存在至少一列低于low阈值”的行,加~取反后,就是删除所有包含低于low的异常列的行。~(df[columns]>high).any(axis=1):同理,这一步会删除所有包含高于high的异常列的行。
核心差异
- 第一段代码是「保留有至少一列正常的行」,这种逻辑几乎会保留全部数据,因为正常行不可能所有列都超出阈值范围。
- 第二段代码是「删除有至少一列异常的行」,这才符合你“删除异常值”的需求:只要行内存在任意一列数据超出分位数阈值,就剔除整行。
内容的提问来源于stack exchange,提问作者Noori Muhammed
相关产品推荐
相关产品推荐

