pandas dataframe columns scaling with sklearn

h5qlskok  于 2023-03-28  发布在  其他
关注(0)|答案(8)|浏览(117)

我有一个包含混合类型列的panda Dataframe ,我想对其中的一些列应用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

我很好奇这是否是进行这种转换的首选/最有效的方法。有没有一种方法可以使用df.apply更好?
我也很惊讶我不能让下面的代码工作:

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

如果我将整个dataframe传递给scaler,它会工作:

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

我很困惑为什么传递一个序列给scaler失败了。在我上面完整的工作代码中,我希望只是传递一个序列给scaler,然后设置dataframe column =为scaled series。

6tqwzwtp

6tqwzwtp1#

我不确定以前版本的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
ezykj2lf

ezykj2lf2#

df = pd.DataFrame(scale.fit_transform(df.values), columns=df.columns, index=df.index)

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

s71maibg

s71maibg3#

像这样?

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
uplii1fm

uplii1fm4#

正如在pir的评论中提到的-.apply(lambda el: scale.fit_transform(el))方法将产生以下警告:
弃用警告:在0.17中不推荐将1d数组作为数据传递,并且在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())

--编辑2018年11月(测试Pandas0.23.4)--
正如Rob Murray在评论中提到的,在pandas的当前版本(v0.23.4)中,.as_matrix()返回FutureWarning。因此,应该将其替换为.values

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()

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

--编辑2019年5月(Pandas测试0.24.2)--
正如joelostblom在评论中提到的,“由于0.24.0,建议使用.to_numpy()而不是.values。”
更新示例:

import pandas as pd
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
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']].to_numpy())
dfTest
      A         B      C
0 -1.995290 -1.571117    big
1  0.436356 -0.603995  small
2  0.460289  0.100818    big
3  0.630058  0.985826  small
4  0.468586  1.088469  small
r1zhe5dt

r1zhe5dt5#

你可以使用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
pvcm50d1

pvcm50d16#

我知道这是一个非常古老的评论,但仍然:
使用双括号(dfTest[['A']])代替单括号(dfTest['A'])
min_max_scaler.fit_transform(dfTest[['A']])
我相信这会给予预期的结果。

kmb7vmvb

kmb7vmvb7#

(针对pandas1.0.5进行测试)
基于@athlonshi答案(它有 ValueError:无法将字符串转换为浮点:'big',on C column),没有警告的完整工作示例:

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
798qvoo8

798qvoo88#

我尝试将min_max_scaler.fit_transform()应用于pd.DataFrame()的多个列
我收到了以下信息:

ValueError: Expected 2D array, got 1D array instead:
array=[0.31428571 0.32142857 0.288... 0.46428571]
Reshape your data either using array.reshape(-1, 1) if your data has a single feature...

我的数据实际上只有一个特征(维度),所以下面的方法有效:

columns_to_normalize = ['a', 'b']

min_max_scaler = preprocessing.MinMaxScaler()

for col in columns_to_normalize:
   df[col] = min_max_scaler.fit_transform(df[col].values.reshape(-1, 1) )
                                                 ^^^^^^^^^^^^^^^^^^^^^^

相关问题