使用>=和<=运算符在Pandas DataFrame中修剪异常值无效的问题排查
问题描述
我有一个包含Blood和Urine列的Pandas DataFrame,示例数据如下:
import pandas as pd import numpy as np data = {"Blood": [26, 48, 41, 80, 66, 40, 7, 73, 60, 61, 52, 76, 40, 53, 2, 9, 100, 59, 99, 82, 100, 82, 62, 73],"Urine": [76, None, 20, 84, 30, 60, 0, 46, 50, 58, None, 66, 40, 22, 66, 18, 0, 60, 1, 78, None, 80, 77, 83]} df = pd.DataFrame(data)
原本使用以下函数,通过>和<运算符修剪指定列的异常值并替换为NaN,输出符合预期:
def trim_outliers_replace_with_nan(df, cols): for col in cols: lo = df[col].quantile(0.025) hi = df[col].quantile(0.975) df[col] = df[col].where((df[col] > lo) & (df[col] < hi), np.nan) return df
但将运算符改为>=和<=后,函数返回的DataFrame完全没有修剪异常值。我已将列统一为object类型,问题依旧,请问问题出在哪里?
根源分析与解决方法
核心问题
将数值列转为object类型后,Pandas无法正确处理列中的None(非数值对象),导致分位数计算逻辑失效:
object类型列中,None不属于数值缺失值范畴,quantile()无法跳过这些非数值元素,计算出的lo和hi会变成列的最小/最大值。- 此时所有数据都满足
>=lo且<=hi的条件,自然没有值被替换为NaN。
解决步骤
- 恢复数值列类型:将
object列转回数值类型,同时把None转为标准的np.nan(数值缺失值):df['Blood'] = pd.to_numeric(df['Blood'], errors='coerce') df['Urine'] = pd.to_numeric(df['Urine'], errors='coerce') - 修正分位数计算与过滤逻辑:明确指定跳过缺失值,确保分位数计算准确,再使用
>=/<=过滤:def trim_outliers_replace_with_nan(df, cols): for col in cols: # 明确跳过缺失值计算分位数,确保取值准确 lo = df[col].quantile(0.025, skipna=True) hi = df[col].quantile(0.975, skipna=True) df[col] = df[col].where((df[col] >= lo) & (df[col] <= hi), np.nan) return df
验证效果
以Blood列为例:
- 0.025分位数为2.575,值为2的行会被替换为
NaN; - 0.975分位数为99.225,值为100的行会被替换为
NaN,异常值修剪正常生效。
内容的提问来源于stack exchange,提问作者Anakin Skywalker
相关产品推荐
相关产品推荐

