You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泰坦尼克号数据集按条件用众数填充Age列缺失值的方法问题排查

问题分析与解决方案:Titanic数据集按Sex和Pclass填充Age缺失值

我来帮你拆解这三种方法遇到的问题,以及对应的修复方案:


一、SimpleImputer方法失效的原因

你遇到的问题主要有两个:

  1. 未正确将处理结果赋值回原DataFrame:fit_transform仅返回处理后的数组,但你没有把这个结果映射到原数据的对应缺失位置。
  2. 索引条件逻辑错误:赋值代码里的(df.Age.isnull()) & (df.Age[(df['Sex'] == 0) & (df['Pclass'] == 1)]) 逻辑混乱,后者返回的是一个Series,和df.Age.isnull()做与运算会导致索引不匹配,无法精准定位需要填充的行。

修复后的代码:

from sklearn.impute import SimpleImputer
import numpy as np

# 定义需要填充的子集条件:性别0、舱位1且Age缺失
fill_condition = (df['Sex'] == 0) & (df['Pclass'] == 1) & (df['Age'].isnull())
# 提取该子集的Age列(转为DataFrame适配SimpleImputer的2D输入要求)
age_subset = df.loc[fill_condition, ['Age']]
# 初始化并拟合填充器
imputer = SimpleImputer(missing_values=np.nan, strategy='most_frequent')
# 填充后将结果赋值回原DataFrame
df.loc[fill_condition, 'Age'] = imputer.fit_transform(age_subset).flatten()

二、fillna()方法失效的原因

这个方法的核心问题是链式索引导致的副本修改:

  • df.loc[(df['Sex'] == 0) & (df['Pclass'] == 1), 'Age'].fillna(...) 这种链式索引(先loc再取'Age')大概率返回的是原DataFrame的副本而非视图,此时用inplace=True只会修改副本,原数据完全不受影响。
  • 另外,df.Age[(df['Sex'] == 0) & (df['Pclass'] == 1)].mode() 返回的是一个Series(可能包含多个众数),直接用int()转换会报错,应该取第一个众数.mode()[0]。

修复后的代码:

# 先计算目标子集的Age众数
mode_age = df.loc[(df['Sex'] == 0) & (df['Pclass'] == 1), 'Age'].mode()[0]
# 直接定位原DataFrame的缺失行赋值,避免链式索引
df.loc[(df['Sex'] == 0) & (df['Pclass'] == 1) & (df['Age'].isnull()), 'Age'] = mode_age

三、单独执行有效但循环报错的原因

循环里的问题集中在变量名、循环范围和索引逻辑上:

  1. 变量名拼写错误:你定义了indices但赋值时用了未定义的ind,直接触发NameError。
  2. 循环范围不匹配:range(1,3)生成的是1和2,但你之前的代码用df['Sex'] == 0,说明Sex的取值是0和1,循环应该写成range(0,2)才能覆盖所有性别类别。
  3. 索引获取逻辑错误:df.loc[(df.Sex == i) & (df.Pclass == j), 'Age'].isnull().index 返回的是该子集中所有行的索引(包括非缺失行),而非仅缺失值的索引,正确做法是直接筛选同时满足性别、舱位、Age缺失的行。
  4. mode()处理不当:和第二种方法一样,mode()返回Series,必须取第一个值.mode()[0],否则多众数场景下int()转换会失败。

修复后的循环代码:

for sex_val in range(0, 2):  # 覆盖Sex的0、1两个取值
    for pclass_val in range(1, 4):  # 覆盖Pclass的1-3三个取值
        # 精准筛选需要填充的行
        fill_condition = (df['Sex'] == sex_val) & (df['Pclass'] == pclass_val) & (df['Age'].isnull())
        if not df.loc[fill_condition].empty:  # 跳过空子集避免报错
            mode_age = df.loc[(df['Sex'] == sex_val) & (df['Pclass'] == pclass_val), 'Age'].mode()[0]
            df.loc[fill_condition, 'Age'] = mode_age

# 验证填充结果
for sex_val in range(0,2):
    for pclass_val in range(1,4):
        missing_count = df.loc[(df['Sex'] == sex_val) & (df['Pclass'] == pclass_val), 'Age'].isnull().sum()
        print(f"Sex={sex_val}, Pclass={pclass_val} 缺失值数量: {missing_count}")

内容的提问来源于stack exchange,提问作者Abdelrahman Abozied

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 03:42:44