python - las columnas del marco de datos pandas escalan con sklearn
scikit-learn dataframe (4)
¿Me gusta esto?
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
Tengo un marco de datos de pandas con columnas de tipo mixto, y me gustaría aplicar min_max_scaler de sklearn a algunas de las columnas. Idealmente, me gustaría hacer estas transformaciones en su lugar, pero aún no he encontrado una manera de hacerlo. He escrito el siguiente código que funciona:
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
Tengo curiosidad si esta es la forma preferida / más eficiente de hacer esta transformación. ¿Hay alguna manera de que pueda usar df.apply que sería mejor?
También me sorprende que no pueda hacer funcionar el siguiente código:
bad_output = min_max_scaler.fit_transform(dfTest[''A''])
Si paso una dataframe completa al escalador, funciona:
dfTest2 = dfTest.drop(''C'', axis = 1) good_output = min_max_scaler.fit_transform(dfTest2) good_output
Estoy confundido por qué se pasa una serie al escalador falla. En mi código de trabajo completo anterior esperaba haber pasado una serie al escalador y luego establecer la columna de marco de datos = a la serie escalada. He visto esta pregunta en algunos otros lugares, pero no he encontrado una buena respuesta. Cualquier ayuda para entender lo que está pasando aquí sería muy apreciada.
Como se menciona en el comentario de pir, el .apply(lambda el: scale.fit_transform(el))
producirá la siguiente advertencia:
Advertencia de depreciación: Pasar matrices de 1d como datos desaprobados en 0.17 y aumentará ValueError en 0.19. Reforme sus datos usando X.reshape (-1, 1) si sus datos tienen una sola característica o X.reshape (1, -1) si contiene una sola muestra.
La conversión de sus columnas a matrices numpy debería hacer el trabajo (prefiero StandardScaler):
from sklearn.preprocessing import StandardScaler
scale = StandardScaler()
dfTest[[''A'',''B'',''C'']] = scale.fit_transform(dfTest[[''A'',''B'',''C'']].as_matrix())
No estoy seguro si las versiones anteriores de los pandas
impidieron esto, pero ahora el siguiente fragmento me funciona perfectamente y produce exactamente lo que desea sin tener que usar 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
Puedes hacerlo solo con 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