通过计算z-score修复pandas异常值的问题咨询
问题定位
你的代码存在两处核心逻辑错误:
- 条件逻辑写反:
np.where的判断规则是「满足条件时返回第二个参数的值,不满足时返回第三个参数的值」。你当前写的逻辑是z-score小于3的正常值被替换为均值,大于等于3的异常值反而保留原值,和需求完全相反。 - z-score计算未处理空值:
stats.zscore默认遇到np.nan会返回np.nan,空值对应的布尔判断结果为False,会被归类到「不满足条件」的分支保留原值,不符合预期。 - (可选优化)你当前计算的均值是包含异常值的全列均值,800、600这类大异常值会大幅拉高均值结果,建议计算均值前先过滤异常值和空值。
正确实现方案
基础版(仅修正逻辑错误,匹配你原有需求)
import pandas as pd import numpy as np from scipy import stats df = pd.DataFrame({'col1' : [1,2,5,8,4,9,3,800,600, np.nan, np.nan]}) # 计算z-score时指定空值处理策略,避免空值导致判断失效 z_scores = stats.zscore(df['col1'], nan_policy='omit') # 修正条件:z-score绝对值≥3的异常值替换为均值,其余值保留 df['col1'] = np.where(np.abs(z_scores) >= 3, df['col1'].mean(), df['col1'])
优化版(排除异常值后计算均值,结果更合理)
import pandas as pd import numpy as np from scipy import stats df = pd.DataFrame({'col1' : [1,2,5,8,4,9,3,800,600, np.nan, np.nan]}) # 先过滤空值计算z-score col_no_na = df['col1'].dropna() z_scores = stats.zscore(col_no_na) # 仅用正常值计算均值,排除异常值干扰 normal_values = col_no_na[np.abs(z_scores) < 3] valid_mean = normal_values.mean() # 替换异常值,也可根据需求补充空值替换逻辑 df['col1'] = np.where(np.abs(stats.zscore(df['col1'], nan_policy='omit')) >= 3, valid_mean, df['col1'])
内容的提问来源于stack exchange,提问作者kms
相关产品推荐
相关产品推荐

