Python中多列(含不同有效值数量)的异常值剔除与截尾均值计算
处理带NaN的数据集:截尾均值计算与异常值剔除
针对10010行100列、各列NaN数量不同的数据集,以下是满足需求的Python实现方案(基于pandas和scipy):
实现步骤与代码
1. 导入依赖库
import pandas as pd from scipy.stats import trim_mean
2. 读取数据集(以CSV为例)
# 替换为你的数据集路径 df = pd.read_csv("your_dataset.csv")
3. 选取任意n列(示例选20列)
# 随机选取20列,无顺序要求 selected_cols = df.sample(n=20, axis=1)
4. 剔除每列异常值并生成新数据集
遍历选中的每一列,先排除NaN,计算上下2.5%分位数,将超出范围的值转为NaN:
# 定义截尾比例:上下各2.5%,总剔除5% trim_ratio = 0.025 processed_df = selected_cols.copy() for col in processed_df.columns: # 提取当前列非NaN的值 non_nan_vals = processed_df[col].dropna() if len(non_nan_vals) == 0: continue # 全是NaN的列跳过处理 # 计算上下分位数 lower_bound = non_nan_vals.quantile(trim_ratio) upper_bound = non_nan_vals.quantile(1 - trim_ratio) # 将超出范围的值设为NaN processed_df[col] = processed_df[col].apply(lambda x: x if (lower_bound <= x <= upper_bound) else pd.NA)
5. 计算每列的截尾均值
利用trim_mean函数直接计算(自动忽略NaN):
trimmed_means = {} for col in processed_df.columns: # 提取非NaN值用于计算 vals = processed_df[col].dropna() if len(vals) == 0: trimmed_means[col] = pd.NA else: # trim_mean的参数是剔除比例,这里上下各2.5%,所以传0.025 trimmed_means[col] = trim_mean(vals, proportiontocut=trim_ratio) # 转换为DataFrame方便查看 trimmed_means_df = pd.DataFrame.from_dict(trimmed_means, orient='index', columns=['截尾均值']) print(trimmed_means_df)
关键说明
- 选取列时,
sample(n=20, axis=1)会随机抽取20列,若需要指定列可直接用df[['col1', 'col2', ...]]替换 - 处理异常值时,先基于非NaN值计算分位数,避免NaN对分位数计算的干扰
- 截尾均值计算使用
scipy.stats.trim_mean,该函数会自动剔除指定比例的首尾数据,计算剩余数据的均值
内容的提问来源于stack exchange,提问作者Anakin Skywalker
相关产品推荐
相关产品推荐

