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

使用ColumnTransformer处理泰坦尼克数据集时列重复问题排查与解决

问题原因分析

出现列重复的核心原因是ColumnTransformer的拼接逻辑与自定义转换器的输出范围不匹配:

  • ColumnTransformer默认会按顺序拼接每个转换器的处理结果,且默认remainder='passthrough'会把未被任何转换器指定的原始列直接追加到结果中。
  • 你的TransformData类如果在fit_transform时返回的是包含原始列+衍生/处理后列的完整数据集,后续标准化、独热编码又对原始列重新处理,拼接后自然会出现重复列。
  • 另外,如果TransformData处理的列与后续数值/类别转换器的列有重叠,也会导致同一列被多次处理后重复出现。
解决方法

1. 修改自定义TransformData类,仅输出需要的新列

让TransformData只返回衍生、缺失值填充后的目标列,不保留原始输入列。示例如下:

import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin

class TransformData(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        # 拟合阶段计算缺失值填充的统计量
        self.age_median = X['Age'].median()
        return self
    
    def transform(self, X):
        X_copy = X.copy()
        # 特征衍生:从Name提取头衔
        X_copy['Title'] = X_copy['Name'].str.extract(' ([A-Za-z]+)\.', expand=False)
        # 缺失值填充
        X_copy['Age'] = X_copy['Age'].fillna(self.age_median)
        # 删除冗余原始列
        X_copy = X_copy.drop(['Name', 'Ticket'], axis=1)
        # 仅返回后续无需重复处理的列
        return X_copy[['Title', 'Age']]

2. 明确划分ColumnTransformer的列分组,避免重叠

将数据集列分为三类,确保各组无重叠,同时设置remainder='drop'丢弃未处理的冗余列:

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder

# 定义不重叠的列分组
transform_cols = ['Name', 'Age']
num_cols = ['Fare', 'SibSp', 'Parch']
cat_cols = ['Sex', 'Embarked', 'Pclass']

# 构建ColumnTransformer
preprocessor = ColumnTransformer(
    transformers=[
        ('custom', TransformData(), transform_cols),
        ('num', StandardScaler(), num_cols),
        ('cat', OneHotEncoder(sparse_output=False, drop='first'), cat_cols)
    ],
    remainder='drop'  # 丢弃未被处理的列,避免残留原始列导致重复
)

# 测试转换
import seaborn as sns
titanic = sns.load_dataset('titanic')
X = titanic.drop('survived', axis=1)
processed_X = preprocessor.fit_transform(X)
# 转换为DataFrame查看结果(可选)
processed_df = pd.DataFrame(processed_X, columns=preprocessor.get_feature_names_out())
print(processed_df.columns)

3. 替代方案:用Pipeline将TransformData作为前置步骤

如果不想修改自定义类的输出,可以先执行TransformData完成初始清洗,再用ColumnTransformer处理后续列:

from sklearn.pipeline import Pipeline

full_pipeline = Pipeline([
    ('custom_transform', TransformData()),
    ('preprocess', ColumnTransformer(
        transformers=[
            ('num', StandardScaler(), ['Fare', 'SibSp', 'Parch', 'Age']),
            ('cat', OneHotEncoder(sparse_output=False, drop='first'), ['Sex', 'Embarked', 'Pclass', 'Title'])
        ],
        remainder='drop'
    ))
])

processed_X = full_pipeline.fit_transform(X)

这种方式下,第一步已经完成特征衍生、缺失值填充和冗余列删除,后续ColumnTransformer仅处理清洗后的列,不会引入重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:22:39