gpt4 book ai didi

python - 用于交叉列列表的一致 ColumnTransformer

转载 作者:行者123 更新时间:2023-12-04 15:25:59 26 4
gpt4 key购买 nike

我想用sklearn.compose.ColumnTransformer始终如一(不是并行的,因此,第二个转换器应该只在第一个转换器之后执行)以这种方式交叉列列表:

log_transformer = p.FunctionTransformer(lambda x: np.log(x))
df = pd.DataFrame({'a': [1,2, np.NaN, 4], 'b': [1,np.NaN, 3, 4], 'c': [1 ,2, 3, 4]})
compose.ColumnTransformer(n_jobs=1,
transformers=[
('num', impute.SimpleImputer() , ['a', 'b']),
('log', log_transformer, ['b', 'c']),
('scale', p.StandardScaler(), ['a', 'b', 'c'])
]).fit_transform(df)

所以,我想用 SimpleImputer'a' , 'b' ,然后 log'b' , 'c' ,然后 StandardScaler'a' , 'b' , 'c' .

但:
  • 我得到 (4, 7) 的数组形状。
  • 我仍然得到Nanab列。

  • 那么,我该如何使用 ColumnTransformer对于不同的列以 Pipeline 的方式?

    更新:
    pipe_1 = pipeline.Pipeline(steps=[
    ('imp', impute.SimpleImputer(strategy='constant', fill_value=42)),
    ])

    pipe_2 = pipeline.Pipeline(steps=[
    ('imp', impute.SimpleImputer(strategy='constant', fill_value=24)),
    ])

    pipe_3 = pipeline.Pipeline(steps=[
    ('scl', p.StandardScaler()),
    ])

    # in the real situation I don't know exactly what cols these arrays contain, so they are not static:
    cols_1 = ['a']
    cols_2 = ['b']
    cols_3 = ['a', 'b', 'c']

    proc = compose.ColumnTransformer(remainder='passthrough', transformers=[
    ('1', pipe_1, cols_1),
    ('2', pipe_2, cols_2),
    ('3', pipe_3, cols_3),
    ])
    proc.fit_transform(df).T

    输出:
    array([[ 1.        ,  2.        , 42.        ,  4.        ],
    [ 1. , 24. , 3. , 4. ],
    [-1.06904497, -0.26726124, nan, 1.33630621],
    [-1.33630621, nan, 0.26726124, 1.06904497],
    [-1.34164079, -0.4472136 , 0.4472136 , 1.34164079]])

    我明白为什么我有 cols 重复, nans而不是缩放值,但是当 cols 不是静态的时,我该如何以正确的方式解决这个问题?

    UPD2:

    当列更改其顺序时可能会出现问题。所以,我想用 FunctionTransformer对于列选择:
    def select_col(X, cols=None):
    return X[cols]

    ct1 = compose.make_column_transformer(
    (p.OneHotEncoder(), p.FunctionTransformer(select_col, kw_args=dict(cols=['a', 'b']))),
    remainder='passthrough'
    )

    ct1.fit(df)

    但是得到这个输出:

    ValueError: No valid specification of the columns. Only a scalar, list or slice of all integers or all strings, or boolean mask is allowed



    我该如何解决?

    最佳答案

    ColumnTransformer的预期用途不同的变压器是并行应用的,而不是顺序应用的。为了实现您想要的结果,想到了三种方法:
    第一种方法:

    pipe_a = Pipeline(steps=[('imp', SimpleImputer()),
    ('scale', StandardScaler())])
    pipe_b = Pipeline(steps=[('imp', SimpleImputer()),
    ('log', log_transformer),
    ('scale', StandardScaler())])
    pipe_c = Pipeline(steps=[('log', log_transformer),
    ('scale', StandardScaler())])
    proc = ColumnTransformer(transformers=[
    ('a', pipe_a, ['a']),
    ('b', pipe_b, ['b']),
    ('c', pipe_c, ['c'])]
    )
    这第二个实际上不起作用 ,因为 ColumnTransformer将重新排列列并忘记名称*,以便后面的列将失败或应用于错误的列。当 sklearn 最终确定如何传递数据帧或特征名称时,这可能会被挽救,或者您现在可以针对您的特定用例对其进行调整。 (* ColumnTransformer 已经有 get_feature_names ,但通过管道传递的实际数据没有该信息。)
    imp_tfm = ColumnTransformer(
    transformers=[('num', impute.SimpleImputer() , ['a', 'b'])],
    remainder='passthrough'
    )
    log_tfm = ColumnTransformer(
    transformers=[('log', log_transformer, ['b', 'c'])],
    remainder='passthrough'
    )
    scl_tfm = ColumnTransformer(
    transformers=[('scale', StandardScaler(), ['a', 'b', 'c'])
    )
    proc = Pipeline(steps=[
    ('imp', imp_tfm),
    ('log', log_tfm),
    ('scale', scl_tfm)]
    )
    第三 ,可能有办法使用 Pipeline切片功能有一个“主”管道,你可以为每个功能削减它......这主要像第一种方法一样工作,在较大管道的情况下可能会节省一些编码,但似乎有点hacky。例如,在这里您可以:
    pipe_a = clone(pipe_b)[1:]
    pipe_c = clone(pipe_b)
    pipe_c.steps[1] = ('nolog', 'passthrough')
    (如果不克隆或以其他方式深度复制 pipe_b ,最后一行将更改 pipe_cpipe_b 。切片机制返回一个副本,因此 pipe_a 并不严格需要被克隆,但我已经让它感觉更安全。不幸的是你不能提供一个不连续的切片,所以 pipe_c = pipe_b[0,2] 不起作用,但你可以像我上面所做的那样将单个切片设置为 "passthrough" 以禁用它们。)

    关于python - 用于交叉列列表的一致 ColumnTransformer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62225230/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com