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

如何通过scikit-learn FunctionTransformer实现涉两列的Age填充函数并消除警告

改进按乘客等级填充年龄缺失值的Scikit-learn Pipeline实现

原代码的问题

  1. 用循环逐行修改数据,效率极低,且直接通过df[column_1].iloc[i]赋值会触发SettingWithCopyWarning——这是因为你可能在修改DataFrame的视图而非原数据,Scikit-learn不推荐原地修改输入数据。
  2. 未复制输入数据,容易引发意外的副作用。

改进后的实现方案

用向量化操作代替循环,先复制输入数据避免原地修改,再根据乘客等级批量填充年龄缺失值,完全符合Scikit-learn的Transformer规范,同时消除警告。

1. 自定义填充函数

import numpy as np
import pandas as pd
from sklearn.preprocessing import FunctionTransformer
from sklearn.pipeline import Pipeline

def impute_age_class(X):
    # 复制输入数据,避免原地修改原数据集
    X_copy = X.copy()
    # 定义乘客等级对应的年龄填充值映射
    age_fill_map = {1: 38, 2: 30, 3: 25}
    # 批量填充:先定位Age为空的行,再根据Pclass匹配对应值
    na_mask = X_copy['Age'].isna()
    X_copy.loc[na_mask, 'Age'] = X_copy.loc[na_mask, 'Pclass'].map(age_fill_map)
    return X_copy

2. 整合到Pipeline中

# 创建FunctionTransformer(无需禁用validate,默认验证输入类型更安全)
age_imputer = FunctionTransformer(impute_age_class)

# 整合进完整Pipeline(可添加其他特征工程/建模步骤)
titanic_pipeline = Pipeline([
    ('age_imputation', age_imputer)
])

# 测试使用(假设df是你的泰坦尼克数据集)
# processed_df = titanic_pipeline.fit_transform(df)

通用化版本(支持自定义列名)

如果需要让函数适配不同列名,可通过参数传递:

def impute_age_class(X, age_col='Age', pclass_col='Pclass'):
    X_copy = X.copy()
    age_fill_map = {1: 38, 2: 30, 3: 25}
    na_mask = X_copy[age_col].isna()
    X_copy.loc[na_mask, age_col] = X_copy.loc[na_mask, pclass_col].map(age_fill_map)
    return X_copy

# 传入列名参数
age_imputer = FunctionTransformer(impute_age_class, kw_args={'age_col':'Age', 'pclass_col':'Pclass'})

为什么这样改能消除警告?

  1. 先复制输入数据,确保原数据不会被修改,符合Scikit-learn Transformer无副作用的设计原则。
  2. 用loc明确修改复制后的DataFrame列,不再操作切片视图,彻底避免SettingWithCopyWarning。
  3. 向量化操作比循环效率提升数倍,处理大规模数据时优势明显。

内容的提问来源于stack exchange,提问作者d-db

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 01:50:25