如何使用skandarn fit_transform与pandas并返回数据帧而不是numpy数组?

lou*_*uic 47 python numpy pandas scikit-learn

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

features = df[["col1", "col2", "col3", "col4"]]
autoscaler = StandardScaler()
features = autoscaler.fit_transform(features)
Run Code Online (Sandbox Code Playgroud)

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

features = features.apply(lambda x: autoscaler.fit_transform(x))
Run Code Online (Sandbox Code Playgroud)

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

/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)))
Run Code Online (Sandbox Code Playgroud)

但这给了:

回溯(最近一次调用最后一次):文件"./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中返回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,in _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 .s",第2885行,在_sanitize_a中 rray raise Exception('数据必须是1维')例外:数据必须是1维的

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

Kev*_*vin 51

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

编辑:根据上述文档的最后一句 更改as_matrix()values,(不会更改结果)as_matrix():

通常,建议使用'.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')
Run Code Online (Sandbox Code Playgroud)

注意,指数是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
Run Code Online (Sandbox Code Playgroud)

现在fit_transformDataFrame得到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]])
Run Code Online (Sandbox Code Playgroud)

将缩放数据分配给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
Run Code Online (Sandbox Code Playgroud)

编辑2:

穿过sklearn-pandas包裹.它专注于让scikit-learn更容易与熊猫一起使用. sklearn-pandas当您需要将多种类型的转换应用于DataFrame更常见的场景的列子集时,此功能特别有用.它已被记录,但这就是您实现我们刚刚执行的转换的方式.

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)
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答,但问题仍然是当从数组创建新数据帧时,行会被重新编号。原始数据框不包含连续编号的行,因为其中一些已被删除。我想我也可以用旧的索引值添加一个 index=[...] 关键字。如果您相应地更新您的答案,我可以接受。 (2认同)
  • 我看到您的最后一步是将 `DataFrameMapper` 的输出转换为 `DataFrame` .. 所以输出不是 *已经* 是 `DataFrame` 吗? (2认同)

Jim*_*Jim 16

重新分配回 df.values 会保留索引和列。

df.values[:] = StandardScaler().fit_transform(df)
Run Code Online (Sandbox Code Playgroud)

  • 在最新版本的 pandas 中对我不起作用。 (4认同)

Dat*_*tor 9

从 sklearn 版本 1.2 开始,estiamtor 可以返回一个保留列名称的 DataFrame。 set_output可以通过调用该set_output方法来配置每个估计器,也可以通过设置来全局配置set_config(transform_output="pandas")

请参阅scikit-learn 1.2 的发布亮点 - 使用 set_output API 进行 Pandas 输出

示例set_output()

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler().set_output(transform="pandas")
Run Code Online (Sandbox Code Playgroud)

示例set_config()

from sklearn import set_config
set_config(transform_output="pandas")
Run Code Online (Sandbox Code Playgroud)


小智 8

features = ["col1", "col2", "col3", "col4"]
autoscaler = StandardScaler()
df[features] = autoscaler.fit_transform(df[features])
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码可以回答问题,但提供有关如何和/或为何解决问题的附加上下文将提高​​答案的长期价值。 (7认同)

小智 8

这与 MinMaxScaler 一起将数组值返回到原始数据帧。它也应该适用于 StandardScaler。

data_scaled = pd.DataFrame(scaled_features, index=df.index, columns=df.columns)
Run Code Online (Sandbox Code Playgroud)

其中,data_scaled 是新的数据帧,scaled_features = 归一化后的数组,df = 我们需要返回索引和列的原始数据帧。


小智 6

import pandas as pd    
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('your file here')
ss = StandardScaler()
df_scaled = pd.DataFrame(ss.fit_transform(df),columns = df.columns)
Run Code Online (Sandbox Code Playgroud)

df_scaled将是“相同”数据帧,仅现在具有缩放值

  • 但这不维护数据类型 (2认同)
  • 无论如何,所有数据类型都不会变成浮点数,因为这是缩放器的唯一输出?您还期望从中得到什么其他成果?@leokury (2认同)

sot*_*kal 6

目前最好的答案是:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler().set_output(transform="pandas")
Run Code Online (Sandbox Code Playgroud)

这会将输出直接转换为数据帧,继承输入数据帧中的所有索引(包括 MultiIndex)和列。

或者您可以使用以下命令将所有变压器的输出全局设置为 pandas:

from sklearn import set_config

set_config(transform_output="pandas")
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息: https://scikit-learn.org/stable/auto_examples/miscellaneous/plot_set_output.html

**注意:请考虑,尤其是在大数据集中,这可能会对计算时间产生负面影响。仅在绝对必要时才使用此功能。


小智 5

对我有用:

from sklearn.preprocessing import StandardScaler

cols = list(train_df_x_num.columns)
scaler = StandardScaler()
train_df_x_num[cols] = scaler.fit_transform(train_df_x_num[cols])
Run Code Online (Sandbox Code Playgroud)

  • 通过额外的支持信息可以改进您的答案。请[编辑]添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以[在帮助中心](/help/how-to-answer)找到有关如何写出好的答案的更多信息。 (2认同)