Normalizar columnas de un marco de datos

Resuelto ahajib asked hace 10 años • 24 respuestas

Tengo un marco de datos en pandas donde cada columna tiene un rango de valores diferente. Por ejemplo:

df:

A     B   C
1000  10  0.5
765   5   0.35
800   7   0.09

¿Alguna idea de cómo puedo normalizar las columnas de este marco de datos donde cada valor está entre 0 y 1?

Mi resultado deseado es:

A     B    C
1     1    1
0.765 0.5  0.7
0.8   0.7  0.18(which is 0.09/0.5)
ahajib avatar Oct 17 '14 05:10 ahajib
Aceptado

una manera fácil usando Pandas : (aquí quiero usar la normalización media)

normalized_df=(df-df.mean())/df.std()

para usar la normalización min-max:

normalized_df=(df-df.min())/(df.max()-df.min())

Editar: para abordar algunas inquietudes, debo decir que Pandas aplica automáticamente la función de columnas en el código anterior.

Cina avatar Jan 08 '2017 11:01 Cina

Puede utilizar el paquete sklearn y sus utilidades de preprocesamiento asociadas para normalizar los datos.

import pandas as pd
from sklearn import preprocessing

x = df.values #returns a numpy array
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(x)
df = pd.DataFrame(x_scaled)

Para obtener más información, consulte la documentación de scikit-learn sobre preprocesamiento de datos: escalamiento de funciones a un rango.

Sandman avatar Oct 16 '2014 23:10 Sandman

Ejemplo detallado de métodos de normalización

  • Normalización de Pandas (imparcial)
  • Normalización de Sklearn (sesgada)
  • ¿Afecta el aprendizaje automático sesgado versus imparcial?
  • Escalado mixto máximo

Referencias: Wikipedia: Estimación insesgada de la desviación estándar

Datos de ejemplo

import pandas as pd
df = pd.DataFrame({
               'A':[1,2,3],
               'B':[100,300,500],
               'C':list('abc')
             })
print(df)
   A    B  C
0  1  100  a
1  2  300  b
2  3  500  c

Normalización utilizando pandas (proporciona estimaciones imparciales)

Al normalizar simplemente restamos la media y dividimos por la desviación estándar.

df.iloc[:,0:-1] = df.iloc[:,0:-1].apply(lambda x: (x-x.mean())/ x.std(), axis=0)
print(df)
     A    B  C
0 -1.0 -1.0  a
1  0.0  0.0  b
2  1.0  1.0  c

Normalización usando sklearn (proporciona estimaciones sesgadas, diferentes de los pandas)

¡Si haces lo mismo sklearnobtendrás un resultado DIFERENTE!

import pandas as pd

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()


df = pd.DataFrame({
               'A':[1,2,3],
               'B':[100,300,500],
               'C':list('abc')
             })
df.iloc[:,0:-1] = scaler.fit_transform(df.iloc[:,0:-1].to_numpy())
print(df)
          A         B  C
0 -1.224745 -1.224745  a
1  0.000000  0.000000  b
2  1.224745  1.224745  c

¿Las estimaciones sesgadas de sklearn hacen que el aprendizaje automático sea menos poderoso?

NO.

La documentación oficial de sklearn.preprocessing.scale establece que es PROBABLE que el uso de un estimador sesgado afecte el rendimiento de los algoritmos de aprendizaje automático y podemos usarlos de forma segura.

De la documentación oficial:

Utilizamos un estimador sesgado para la desviación estándar, equivalente a numpy.std(x, ddof=0). Tenga en cuenta que es poco probable que la elección de ddofafecte el rendimiento del modelo.

¿Qué pasa con la escala MinMax?

No hay cálculo de desviación estándar en la escala MinMax. Entonces el resultado es el mismo tanto en pandas como en scikit-learn.

import pandas as pd
df = pd.DataFrame({
               'A':[1,2,3],
               'B':[100,300,500],
             })
(df - df.min()) / (df.max() - df.min())
     A    B
0  0.0  0.0
1  0.5  0.5
2  1.0  1.0


# Using sklearn
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler() 
arr_scaled = scaler.fit_transform(df) 

print(arr_scaled)
[[0.  0. ]
 [0.5 0.5]
 [1.  1. ]]

df_scaled = pd.DataFrame(arr_scaled, columns=df.columns,index=df.index)
print(df_scaled)
     A    B
0  0.0  0.0
1  0.5  0.5
2  1.0  1.0
BhishanPoudel avatar Jul 17 '2019 01:07 BhishanPoudel

Basado en esta publicación: https://stats.stackexchange.com/questions/70801/how-to-normalize-data-to-0-1-range

Puedes hacer lo siguiente:

def normalize(df):
    result = df.copy()
    for feature_name in df.columns:
        max_value = df[feature_name].max()
        min_value = df[feature_name].min()
        result[feature_name] = (df[feature_name] - min_value) / (max_value - min_value)
    return result

No necesitas seguir preocupándote por si tus valores son negativos o positivos. Y los valores deberían estar bien distribuidos entre 0 y 1.

Michael Aquilina avatar Apr 15 '2015 13:04 Michael Aquilina