用sklearn扩展的pandas数据帧列

fly*_*all 98 python dataframe pandas scikit-learn

我有一个带有混合类型列的pandas数据帧,我想将sklearn的min_max_scaler应用于某些列.理想情况下,我想在适当的位置进行这些转换,但还没有想出办法.我编写了以下代码:

import pandas as pd
import numpy as np
from sklearn import preprocessing

scaler = preprocessing.MinMaxScaler()

dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],'B':[103.02,107.26,110.35,114.23,114.68], 'C':['big','small','big','small','small']})
min_max_scaler = preprocessing.MinMaxScaler()

def scaleColumns(df, cols_to_scale):
    for col in cols_to_scale:
        df[col] = pd.DataFrame(min_max_scaler.fit_transform(pd.DataFrame(dfTest[col])),columns=[col])
    return df

dfTest

    A   B   C
0    14.00   103.02  big
1    90.20   107.26  small
2    90.95   110.35  big
3    96.27   114.23  small
4    91.21   114.68  small

scaled_df = scaleColumns(dfTest,['A','B'])
scaled_df

A   B   C
0    0.000000    0.000000    big
1    0.926219    0.363636    small
2    0.935335    0.628645    big
3    1.000000    0.961407    small
4    0.938495    1.000000    small
Run Code Online (Sandbox Code Playgroud)

我很好奇这是否是进行此转换的首选/最有效方式.有没有办法可以使用更好的df.apply?

我也很惊讶我无法使用以下代码:

bad_output = min_max_scaler.fit_transform(dfTest['A'])

如果我将整个数据帧传递给缩放器,它可以工作:

dfTest2 = dfTest.drop('C', axis = 1) good_output = min_max_scaler.fit_transform(dfTest2) good_output

我很困惑为什么将系列传递给缩放器失败.在我上面的完整工作代码中,我曾希望只将一系列文件传递给scaler,然后将dataframe column =设置为缩放系列.我已经看到这个问题问了其他一些地方,但还没有找到一个好的答案.任何帮助了解这里发生的事情将不胜感激!

Let*_*zee 153

我不确定以前的版本是否pandas阻止了这一点,但现在以下代码片段对我来说非常有效,并且无需使用即可生成您想要的内容apply

>>> import pandas as pd
>>> from sklearn.preprocessing import MinMaxScaler


>>> scaler = MinMaxScaler()

>>> dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],
                           'B':[103.02,107.26,110.35,114.23,114.68],
                           'C':['big','small','big','small','small']})

>>> dfTest[['A', 'B']] = scaler.fit_transform(dfTest[['A', 'B']])

>>> dfTest
          A         B      C
0  0.000000  0.000000    big
1  0.926219  0.363636  small
2  0.935335  0.628645    big
3  1.000000  0.961407  small
4  0.938495  1.000000  small
Run Code Online (Sandbox Code Playgroud)

  • 整齐!一个更通用的版本`df [df.columns] = scaler.fit_transform(df [df.columns])` (59认同)
  • @RajeshThevar外括号是pandas的典型选择器括号,告诉pandas从数据帧中选择一列.内括号表示列表.您正在将列表传递给pandas选择器.如果你只使用单个括号 - 一个列名后跟另一个,用逗号分隔 - pandas解释这就像你试图从具有多级列(MultiIndex)的数据框中选择一个列并抛出一个keyerror . (6认同)
  • 实用说明:对于那些使用训练/测试数据拆分的人,您只希望适合您的训练数据,而不是您的测试数据。 (4认同)
  • 要缩放除时间戳列之外的所有列,请与 `columns =df.columns.drop('timestamps') df[df.columns] = scaler.fit_transform(df[df.columns]` 结合使用 (2认同)
  • 更正@intotecho 的评论。您应该执行 `columns = df.columns.drop('timestamps')` 和 `df[columns] = scaler.fit_transform(df[columns])`。方括号中应该是“columns”,而不是“df.columns” (2认同)

小智 19

像这样?

dfTest = pd.DataFrame({
           'A':[14.00,90.20,90.95,96.27,91.21],
           'B':[103.02,107.26,110.35,114.23,114.68], 
           'C':['big','small','big','small','small']
         })
dfTest[['A','B']] = dfTest[['A','B']].apply(
                           lambda x: MinMaxScaler().fit_transform(x))
dfTest

    A           B           C
0   0.000000    0.000000    big
1   0.926219    0.363636    small
2   0.935335    0.628645    big
3   1.000000    0.961407    small
4   0.938495    1.000000    small
Run Code Online (Sandbox Code Playgroud)

  • 当我运行这个脚本时,我得到了一堆DeprecationWarnings.应该如何更新? (3认同)
  • 一个更简单的版本:dfTest[['A','B']] = dfTest[['A','B']].apply(MinMaxScaler().fit_transform) (2认同)

Low*_*ond 10

正如pir的评论中提到的那样 - 该.apply(lambda el: scale.fit_transform(el))方法将产生以下警告:

弃用警告:传递1d数组作为数据在0.17中弃用,并将在0.19中引发ValueError.如果数据具有单个要素,则使用X.reshape(-1,1)重新整形数据;如果包含单个样本,则使用X.reshape(1,-1)重新整形数据.

将列转换为numpy数组应该完成这项工作(我更喜欢StandardScaler):

from sklearn.preprocessing import StandardScaler
scale = StandardScaler()

dfTest[['A','B','C']] = scale.fit_transform(dfTest[['A','B','C']].as_matrix())
Run Code Online (Sandbox Code Playgroud)

- 编辑 2018年11月 -

正如Rob Murray在评论中提到的那样,在当前(v0.23.4)版本的熊猫.as_matrix()回归中FutureWarning.因此,它应该被替换为.values:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

scaler.fit_transform(dfTest[['A','B']].values)
Run Code Online (Sandbox Code Playgroud)


ath*_*shi 8

df = pd.DataFrame(scale.fit_transform(df.values), columns=df.columns, index=df.index)
Run Code Online (Sandbox Code Playgroud)

这应该在没有折旧警告的情况下起作用。

  • 或 `df[df.columns] = scale.fit_transform(df)` (4认同)

小智 8

我知道这是一个非常古老的评论,但仍然:

不使用单括号(dfTest['A']),而使用双括号(dfTest[['A']])

IE:min_max_scaler.fit_transform(dfTest[['A']])

我相信这会产生预期的结果。


CT *_*Zhu 7

你只能使用 pandas:

In [235]:
dfTest = pd.DataFrame({'A':[14.00,90.20,90.95,96.27,91.21],'B':[103.02,107.26,110.35,114.23,114.68], 'C':['big','small','big','small','small']})
df = dfTest[['A', 'B']]
df_norm = (df - df.min()) / (df.max() - df.min())
print df_norm
print pd.concat((df_norm, dfTest.C),1)

          A         B
0  0.000000  0.000000
1  0.926219  0.363636
2  0.935335  0.628645
3  1.000000  0.961407
4  0.938495  1.000000
          A         B      C
0  0.000000  0.000000    big
1  0.926219  0.363636  small
2  0.935335  0.628645    big
3  1.000000  0.961407  small
4  0.938495  1.000000  small
Run Code Online (Sandbox Code Playgroud)

  • 我知道我只能在熊猫中做到这一点,但我可能想最终应用一种不同于自己编写的sklearn方法.我更有兴趣弄清楚为什么申请系列不能像我预期的那样工作,而不是我提出一个更简单的解决方案.我的下一步将是运行RandomForestRegressor,我想确保我理解Pandas和sklearn如何协同工作. (5认同)
  • **这个答案是危险的**因为`df.max() - df.min()`可以是0,导致异常.而且,`df.min()`被计算两次,效率很低.请注意,`df.ptp()`相当于`df.max() - df.min()`. (2认同)

小智 6

(针对 pandas 1.0.5进行测试)
基于 @athlonshi 答案(它有ValueError: Could not conversion string to float: 'big',在 C 列上),完整的工作示例,没有警告:

import pandas as pd
from sklearn.preprocessing import MinMaxScaler
scale = preprocessing.MinMaxScaler()

df = pd.DataFrame({
           'A':[14.00,90.20,90.95,96.27,91.21],
           'B':[103.02,107.26,110.35,114.23,114.68], 
           'C':['big','small','big','small','small']
         })
print(df)
df[["A","B"]] = pd.DataFrame(scale.fit_transform(df[["A","B"]].values), columns=["A","B"], index=df.index)
print(df)

       A       B      C
0  14.00  103.02    big
1  90.20  107.26  small
2  90.95  110.35    big
3  96.27  114.23  small
4  91.21  114.68  small
          A         B      C
0  0.000000  0.000000    big
1  0.926219  0.363636  small
2  0.935335  0.628645    big
3  1.000000  0.961407  small
4  0.938495  1.000000  small
Run Code Online (Sandbox Code Playgroud)