python pandas scikit-learn dataframe

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