Normalizar columnas de dataframe de pandas.

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

df:

ABC 1000 10 0.5 765 5 0.35 800 7 0.09 

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

Mi salida deseada es:

 ABC 1 1 1 0.765 0.5 0.7 0.8 0.7 0.18(which is 0.09/0.5) 

Puede usar el paquete sklearn y sus utilidades de preproceso asociadas para normalizar los datos.

 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 = pandas.DataFrame(x_scaled) 

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

Una forma fácil de usar Pandas : (aquí quiero usar la normalización de la media)

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

Para utilizar la normalización min-max:

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

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 necesita preocuparse por si sus valores son negativos o positivos. Y los valores deben estar bien distribuidos entre 0 y 1.

Si te gusta usar el paquete sklearn, puedes mantener los nombres de columna e índice usando pandas loc como:

 from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() scaled_values = scaler.fit_transform(df) df.loc[:,:] = scaled_values 

Su problema es en realidad una simple transformación que actúa sobre las columnas:

 def f(s): return s/s.max() frame.apply(f, axis=0) 

O incluso más terso:

  frame.apply(lambda x: x/x.max(), axis=0) 

Lo simple es hermoso:

 df["A"] = df["A"] / df["A"].max() df["B"] = df["B"] / df["B"].max() df["C"] = df["C"] / df["C"].max() 

Puedes crear una lista de columnas que quieras normalizar.

 column_names_to_normalize = ['A', 'E', 'G', 'sadasdsd', 'lol'] x = df[column_names_to_normalize].values x_scaled = min_max_scaler.fit_transform(x) df_temp = pd.DataFrame(x_scaled, columns=column_names_to_normalize, index = df.index) df[column_names_to_normalize] = df_temp 

Tu Pandas Dataframe ahora está normalizado solo en las columnas que deseas


Sin embargo , si desea lo contrario , seleccione una lista de columnas que NO quiera normalizar, simplemente puede crear una lista de todas las columnas y eliminar las que no desee.

 column_names_to_not_normalize = ['B', 'J', 'K'] column_names_to_normalize = [x for x in list(df) if x not in column_names_to_not_normalize ] 

Creo que una mejor manera de hacerlo en pandas es simplemente

 df = df/df.max().astype(np.float64) 

Editar Si en su dataframe hay números negativos, debe usar en su lugar

 df = df/df.loc[df.abs().idxmax()].astype(np.float64) 

La solución dada por Sandman y Praveen está muy bien. El único problema con eso si tiene variables categóricas en otras columnas de su dataframe, este método necesitará algunos ajustes.

Mi solución a este tipo de problema es la siguiente:

  from sklearn import preprocesing x = pd.concat([df.Numerical1, df.Numerical2,df.Numerical3]) min_max_scaler = preprocessing.MinMaxScaler() x_scaled = min_max_scaler.fit_transform(x) x_new = pd.DataFrame(x_scaled) df = pd.concat([df.Categoricals,x_new]) 
 def normalize(x): try: x = x/np.linalg.norm(x,ord=1) return x except : raise data = pd.DataFrame.apply(data,normalize) 

Desde el documento de pandas, la estructura DataFrame puede aplicar una operación (función) a sí misma.

 DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds) 

Aplica la función a lo largo del eje de entrada de DataFrame. Los objetos pasados ​​a las funciones son objetos de serie que tienen un índice, ya sea el índice de DataFrame (axis = 0) o las columnas (axis = 1). El tipo de devolución depende de si la función pasada se agrega o el argumento de reducción si el DataFrame está vacío.

Puede aplicar una función personalizada para operar el DataFrame.

La siguiente función calcula la puntuación Z:

 def standardization(dataset): """ Standardization of numeric fields, where all values will have mean of zero and standard deviation of one. (z-score) Args: dataset: A `Pandas.Dataframe` """ dtypes = list(zip(dataset.dtypes.index, map(str, dataset.dtypes))) # Normalize numeric columns. for column, dtype in dtypes: if dtype == 'float32': dataset[column] -= dataset[column].mean() dataset[column] /= dataset[column].std() return dataset 

Puedes hacer esto en una línea

 DF_test = DF_test.sub(DF_test.mean(axis=0), axis=1)/DF_test.mean(axis=0) 

toma la media para cada una de las columnas y luego la resta (media) de cada fila (la media de la columna particular se resta solo de su fila) y se divide solo por la media. Finalmente, lo que obtenemos es el conjunto de datos normalizado.