У мене є фрейм даних 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.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
Мене бентежить, чому передача серії на скалер не вдається. У своєму повному робочому коді вище я сподівався просто передати серію на скалер, а потім встановити стовпчик фрейму даних = до масштабованого ряду. Я бачив це запитання у кількох інших місцях, але не знайшов гарної відповіді. Будь-яка допомога в розумінні того, що тут відбувається, буде дуже вдячна!
bad_output = in_max_scaler.fit_transform(dfTest['A'].values)
теж не працював. @larsmans - так, я думав про те, щоб піти цим маршрутом, це просто здається клопотом. Я не знаю, помилка чи ні, що Pandas може передавати повний кадр даних функції sklearn, але не серію. Моє розуміння фрейму даних полягало в тому, що це вислів серії. Читаючи в книзі "Python для аналізу даних", він зазначає, що панди побудовані на вершині нуме, щоб зробити їх легким у використанні в NumPy-орієнтованих додатках.
bad_output = min_max_scaler.fit_transform(dfTest['A'].values)
?values
Доступ до атрибута повертає масив numpy, чомусь іноді scikit learn api правильно викликає правильний метод, завдяки якому панди повертають numpy масив, а іноді - ні.