使用df.drop(index=array)删除分组数据异常值时出现KeyError的问题求助
df.drop(index=array)删除分组数据异常值时出现KeyError的问题求助
你好!这个KeyError问题的根源其实很好理解——你用np.where得到的[15,25,34,53]是子DataFrame df2里的相对位置索引(也就是从0开始计数的行位置),但df2的行标签(index)还是继承自原始DataFrame df的原始索引值,并不是从0连续排列的,所以直接用这些位置数字去调用drop,自然找不到对应的行标签,就报错了。
下面给你两种可靠的解决方法:
方法一:用布尔索引过滤(推荐)
不需要用np.where获取位置,直接生成布尔掩码筛选非异常值,代码更直观,也不会有索引不匹配的问题:
import pandas as pd import numpy as np # Load the dataset df = pd.read_csv('.xxx.csv') def remove_outlier_using_IQR(df: pd.DataFrame, name_column: str, value: int) -> pd.DataFrame: """ Remove outliers using IQR in the 'name_column'. Args: df (pd.DataFrame): The DataFrame containing the columns for outlier removal. name_column (str): The name of the column containing outliers to be removed. value: Value in name column for outlier removal. Returns: pd.DataFrame: The DataFrame with outliers in 'name_column' removed. """ # 筛选目标分组,加copy避免SettingWithCopyWarning df2 = df[df[name_column]==value].copy() Q1 = df2['final_test'].quantile(0.25) Q3 = df2['final_test'].quantile(0.75) IQR = Q3 - Q1 lower = Q1 - 1.5*IQR upper = Q3 + 1.5*IQR # 生成非异常值的布尔掩码 mask = (df2['final_test'] > lower) & (df2['final_test'] < upper) # 过滤出非异常值的行 df2_clean = df2[mask] # 合并其他分组和清理后的目标分组 df3 = df[df[name_column]!=value] df_merged = pd.concat([df2_clean, df3], ignore_index=False, sort=False) return df_merged # 使用函数清理异常值 df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=0) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=1) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=2) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=3) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=4)
方法二:获取正确的行标签再drop
如果你坚持要用drop方法,需要把np.where得到的位置索引转换成df2对应的行标签,而不是直接用位置数字:
import pandas as pd import numpy as np # Load the dataset df = pd.read_csv('.xxx.csv') def remove_outlier_using_IQR(df: pd.DataFrame, name_column: str, value: int) -> pd.DataFrame: """ Remove outliers using IQR in the 'name_column'. Args: df (pd.DataFrame): The DataFrame containing the columns for outlier removal. name_column (str): The name of the column containing outliers to be removed. value: Value in name column for outlier removal. Returns: pd.DataFrame: The DataFrame with outliers in 'name_column' removed. """ df2 = df[df[name_column]==value].copy() Q1 = df2['final_test'].quantile(0.25) Q3 = df2['final_test'].quantile(0.75) IQR = Q3 - Q1 lower = Q1 - 1.5*IQR upper = Q3 + 1.5*IQR # 获取异常值对应的行标签,而非位置索引 upper_indices = df2[df2['final_test'] >= upper].index lower_indices = df2[df2['final_test'] <= lower].index # 删除异常值行 df2.drop(index=upper_indices, inplace=True) df2.drop(index=lower_indices, inplace=True) df3 = df[df[name_column]!=value] df_merged = pd.concat([df2,df3], ignore_index=False, sort=False) return df_merged # 使用函数清理异常值 df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=0) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=1) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=2) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=3) df = remove_outlier_using_IQR(df=df, name_column='hours_per_week', value=4)
另外补充两个小细节:
- 给
df2赋值时加上.copy(),可以避免后续操作触发SettingWithCopyWarning; - 我把你函数注释里大小写不一致的
Value改成了小写value,和参数定义保持统一。
备注:内容来源于stack exchange,提问作者Tyl
相关产品推荐
相关产品推荐

