Ho un frame di dati Panda con colonne di tipo misto e vorrei applicare min_max_scaler di sklearn ad alcune delle colonne. Idealmente, mi piacerebbe fare queste trasformazioni sul posto, ma non ho ancora trovato un modo per farlo. Ho scritto il seguente codice che funziona:
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
Sono curioso di sapere se questo è il modo preferito / più efficiente per fare questa trasformazione. C'è un modo per usare df.apply che sarebbe meglio?
Sono anche sorpreso di non riuscire a far funzionare il seguente codice:
bad_output = min_max_scaler.fit_transform(dfTest['A'])
Se passo un intero frame di dati allo scaler, funziona:
dfTest2 = dfTest.drop('C', axis = 1)
good_output = min_max_scaler.fit_transform(dfTest2)
good_output
Sono confuso perché il passaggio di una serie allo scaler non riesce. Nel mio codice di lavoro completo sopra, avevo sperato di passare una serie al ridimensionatore e quindi impostare la colonna dataframe = sulla serie ridimensionata. Ho visto questa domanda posta in pochi altri posti, ma non ho trovato una buona risposta. Qualsiasi aiuto per capire cosa sta succedendo qui sarebbe molto apprezzato!
bad_output = in_max_scaler.fit_transform(dfTest['A'].values)
non ha funzionato neanche. @larsmans - sì, avevo pensato di percorrere questa strada, mi sembra solo una seccatura. Non so se sia un bug o meno che Panda possa passare un frame di dati completo a una funzione sklearn, ma non a una serie. La mia comprensione di un dataframe era che si tratta di un dettato di serie. Leggendo nel libro "Python for Data Analysis", si afferma che i panda sono costruiti su numpy per renderlo facile da usare nelle applicazioni incentrate su NumPy.
bad_output = min_max_scaler.fit_transform(dfTest['A'].values)
? l'accessovalues
all'attributo restituisce un array intorpidito, per qualche motivo a volte lo scikit learn api chiamerà correttamente il metodo giusto che rende i panda restituisce un array intorpidito e talvolta no.