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

为何对OneHot编码后的Female[0]列做Log变换会作用于所有列?

问题:OneHot编码后仅对指定列应用log1p,却多列被变换

我已使用OneHotEncoder对Gender列完成编码,希望仅对编码后的Female[0]列应用log1p变换,但实际编码后的两列都被执行了变换。以下是我的代码、变换前后的数组输出:

代码

import pandas as p
from sklearn.preprocessing import FunctionTransformer, OneHotEncoder
from sklearn.compose import ColumnTransformer
import numpy as n

customer=p.read_csv('/content/Customers.csv')
customer.drop(['CustomerID','Profession','Family Size','Work Experience'],axis=1,inplace=True)
column=ColumnTransformer(
    [
        ('ohe_gender',OneHotEncoder(sparse=False,dtype=n.int32),[0])
    ],remainder='passthrough'
)
function=ColumnTransformer(
    [
        ('function',FunctionTransformer(n.log1p),[0])
    ],remainder='passthrough'
)
s=column.fit_transform(customer)
function.fit_transform(s)

变换前(OHE编码后)的数组

array([[     0,      1,     19,  15000,     39],
       [     0,      1,     21,  35000,     81],
       [     1,      0,     20,  86000,      6],
       ...,
       [     0,      1,     87,  90961,     14],
       [     0,      1,     77, 182109,      4],
       [     0,      1,     90, 110610,     52]])

变换后的数组

array([[0.00000000e+00, 6.93147181e-01, 1.90000000e+01, 1.50000000e+04, 3.90000000e+01],
       [0.00000000e+00, 6.93147181e-01, 2.10000000e+01, 3.50000000e+04, 8.10000000e+01],
       [6.93147181e-01, 0.00000000e+00, 2.00000000e+01, 8.60000000e+04, 6.00000000e+00],
       ...,
       [0.00000000e+00, 6.93147181e-01, 8.70000000e+01, 9.09610000e+04, 1.40000000e+01],
       [0.00000000e+00, 6.93147181e-01, 7.70000000e+01, 1.82109000e+05, 4.00000000e+00],
       [0.00000000e+00, 6.93147181e-01, 9.00000000e+01, 1.10610000e+05, 5.20000000e+01]]

原因分析

从变换后的数组可以看到,只有OHE生成的前两列被log1p处理,后续列(年龄、收入等)保持原样,说明remainder='passthrough'正常工作。核心问题是:

  • 若你的代码确实使用[0]作为列选择器,理论上仅第0列会被处理,但输出显示第1列也被变换,大概率是代码笔误(比如列选择器误写为[0,1]),或者scikit-learn版本兼容问题导致列选择逻辑异常。
  • 另一种可能是你误判了结果:第1列原始值为1时,log1p(1)=0.693,若代码未选中该列,它应保持原始值1,但你的输出中该列值变为0.693,说明代码确实对第1列也应用了变换。

解决方法

方法1:手动指定列处理(最直接)

跳过ColumnTransformer,直接对numpy数组的目标列进行变换:

s = column.fit_transform(customer)
# 仅对第0列应用log1p
s[:, 0] = n.log1p(s[:, 0])

方法2:确保ColumnTransformer正确选择列

检查并修正列选择器,同时显式设置FunctionTransformer的validate=True以避免形状错误:

function = ColumnTransformer(
    [
        ('log1p_col0', FunctionTransformer(n.log1p, validate=True), [0])
    ], remainder='passthrough'
)
result = function.fit_transform(s)

方法3:在Pipeline中组合OHE与log1p变换

将OHE和指定列的log1p变换整合到一个Pipeline中,避免分步处理的错误:

from sklearn.pipeline import Pipeline

# 定义Gender列的处理流程:OHE -> 仅对第0列log1p
gender_pipeline = Pipeline([
    ('ohe', OneHotEncoder(sparse=False, dtype=n.int32)),
    ('log_col0', ColumnTransformer([
        ('log1p', FunctionTransformer(n.log1p), [0])
    ], remainder='passthrough'))
])

# 整体预处理流程
preprocessor = ColumnTransformer(
    [('gender_process', gender_pipeline, [0])],
    remainder='passthrough'
)

result = preprocessor.fit_transform(customer)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:52:03