首页 文章

如何使用pleas sklearn fit_transform并返回数据帧而不是numpy数组?

提问于
浏览
27

我想将缩放(使用sklearn.preprocessing中的StandardScaler())应用到pandas数据帧 . 以下代码返回一个numpy数组,因此我丢失了所有列名和indeces . 这不是我想要的 .

features = df[["col1", "col2", "col3", "col4"]]
autoscaler = StandardScaler()
features = autoscaler.fit_transform(features)

我在网上找到的“解决方案”是:

features = features.apply(lambda x: autoscaler.fit_transform(x))

它似乎有效,但会导致弃用警告:

/usr/lib/python3.5/site-packages/sklearn/preprocessing/data.py:583:DreprecationWarning:传递1d数组作为数据在0.17中弃用,并将在0.19中引发ValueError . 如果数据具有单个要素,则使用X.reshape(-1,1)重新整形数据;如果包含单个样本,则使用X.reshape(1,-1)重新整形数据 .

我因此尝试过:

features = features.apply(lambda x: autoscaler.fit_transform(x.reshape(-1, 1)))

但是这给了:

回溯(最近一次调用最后一次):文件“./analyse.py”,第91行,在features = features.apply中(lambda x:autoscaler.fit_transform(x.reshape(-1,1)))文件“/ usr /lib/python3.5/site-packages/pandas/core/frame.py“,第3972行,在apply return self._apply_standard(f,axis,reduce = reduce)文件”/usr/lib/python3.5/site -packages / pandas / core / frame.py“,第4081行,在_apply_standard结果= self._constructor(data = results,index = index)文件”/usr/lib/python3.5/site-packages/pandas/core/ frame.py“,第226行,在init mgr = self._init_dict(data,index,columns,dtype = dtype)文件”/usr/lib/python3.5/site-packages/pandas/core/frame.py“,第363行,在_init_dict中dtype = dtype)文件“/usr/lib/python3.5/site-packages/pandas/core/frame.py”,第5163行,在_arrays_to_mgr arrays = _homogenize(arrays,index,dtype)File“ /usr/lib/python3.5/site-packages/pandas/core/frame.py“,第5477行,_homogenize raise_cast_failure = False)文件”/usr/lib/python3.5/site-packages/pandas/core/ series.py“,第2885行,在_sanitize中_array raise Exception('Data必须是1维')例外:数据必须是1维的

如何将缩放应用于pandas数据帧,使数据帧保持不变?如果可能的话,不要复制数据 .

1 回答

  • 33

    您可以使用as_matrix()将DataFrame转换为numpy数组 . 随机数据集上的示例:

    Edit: 根据上述 as_matrix() docs的最后一句,将 as_matrix() 更改为 values ,(它不会更改结果):

    通常,建议使用'.values' .

    import pandas as pd
    import numpy as np #for the random integer example
    df = pd.DataFrame(np.random.randint(0.0,100.0,size=(10,4)),
                  index=range(10,20),
                  columns=['col1','col2','col3','col4'],
                  dtype='float64')
    

    注意,指数是10-19:

    In [14]: df.head(3)
    Out[14]:
        col1    col2    col3    col4
        10  3   38  86  65
        11  98  3   66  68
        12  88  46  35  68
    

    现在 fit_transform DataFrame获取 scaled_features array

    from sklearn.preprocessing import StandardScaler
    scaled_features = StandardScaler().fit_transform(df.values)
    
    In [15]: scaled_features[:3,:] #lost the indices
    Out[15]:
    array([[-1.89007341,  0.05636005,  1.74514417,  0.46669562],
           [ 1.26558518, -1.35264122,  0.82178747,  0.59282958],
           [ 0.93341059,  0.37841748, -0.60941542,  0.59282958]])
    

    将缩放数据分配给DataFrame(注意:使用 indexcolumns 关键字参数来保留原始索引和列名称:

    scaled_features_df = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)
    
    In [17]:  scaled_features_df.head(3)
    Out[17]:
        col1    col2    col3    col4
    10  -1.890073   0.056360    1.745144    0.466696
    11  1.265585    -1.352641   0.821787    0.592830
    12  0.933411    0.378417    -0.609415   0.592830
    

    Edit 2:

    来到sklearn-pandas包裹 . 它专注于让scikit-learn更容易与熊猫一起使用 . 当您需要将多种类型的转换应用于 DataFrame 的列子集时, sklearn-pandas 特别有用,这是一种更常见的方案 . 它's documented, but this is how you'd实现了我们刚刚进行的转型 .

    from sklearn_pandas import DataFrameMapper
    
    mapper = DataFrameMapper([(df.columns, StandardScaler())])
    scaled_features = mapper.fit_transform(df.copy(), 4)
    scaled_features_df = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)
    

相关问题