масштабирование столбцов фрейма данных pandas с помощью sklearn



у меня есть фрейм данных pandas со столбцами смешанного типа, и я хотел бы применить min_max_scaler sklearn к некоторым столбцам. В идеале, я хотел бы сделать эти преобразования, но не придумал, как это сделать. Я написал следующий код, который работает:



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.применить что было бы лучше?



Я также удивлен, что не могу получить следующий код для работы:



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



Я в замешательстве, почему передача серии в скалер не удается. В моем полном рабочем коде выше я надеялся просто передать серию в скалер, а затем установить столбец dataframe = в масштабируемый ряд. Я видел этот вопрос, заданный в нескольких других местах, но не нашел хорошего ответа. Любая помощь в понимании того, что здесь происходит, будет очень признателен!

830   4  

4 ответов:

Я не уверен, что предыдущие версии 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

Как это?

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

Вы можете сделать это с помощью 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

Как уже упоминалось в комментарии pir-the .apply(lambda el: scale.fit_transform(el)) метод выдаст следующее предупреждение:

DeprecationWarning: передача массивов 1d в качестве данных устарела в 0.17 и поднимет ValueError в 0.19. Измените свои данные либо с помощью X. изменить форму (-1, 1) Если ваши данные имеют один объект или X. изменить форму(1, -1) если он содержит один образец.

преобразование столбцов в массивы numpy должно выполнять эту работу (я предпочитаю StandardScaler):

from sklearn.preprocessing import StandardScaler
scale = StandardScaler()

dfTest[['A','B','C']] = scale.fit_transform(dfTest[['A','B','C']].as_matrix())

Comments

    Ничего не найдено.