Tengo un marco de datos en pandas donde cada columna tiene un rango de valores diferente. Por ejemplo:
d.f.:
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)
hay una función de aplicación, por ejemplo, frame.apply(f, axis=1) donde f es una función que hace algo con una fila…
– tschm
16/10/2014 a las 22:30
La normalización podría no ser la redacción más adecuada, ya que documentación de scikit-learn lo define como “el proceso de escalar muestras individuales para tener una norma unitaria” (es decir, fila por fila, si lo entiendo correctamente).
– Skippy el Gran Gourou
5 de marzo de 2019 a las 16:58
No lo entiendo, ¿por qué la escala min_max se considera normalización? normal tiene que tener significado en el sentido de distribución normal con media cero y varianza 1.
– Policía de desbordamiento
21 de abril de 2019 a las 2:21
Si está visitando esta pregunta en 2020 o posterior, mire la respuesta de @Poudel, obtendrá una respuesta diferente de normalización si usa pandas vs sklearn.
– BhishanPoudel
29 de enero de 2020 a las 20:10
@Poudel es esto debido a la ddof ¿argumento?
– escarcha
4 abr 2020 a las 20:26
China
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 columna en el código anterior.
¿Se puede hacer de alguna manera con la función de ventana? Lo que quiero decir con eso es calcular max () y min () en función de, por ejemplo, las últimas 10 observaciones.
– Krakowi
15 de noviembre de 2019 a las 10:12
si quieres guardar alguna columna, hazlo normalized_df['TARGET'] = df['TARGET']
–Roman Filippov
22 de diciembre de 2019 a las 9:53
esta es una buena solución, pero necesita muchas comprobaciones menos hermosas para evitar errores de división por cero
-Teddy Ward
7 mayo 2020 a las 21:26
Hice una nueva pregunta; Si alguien sabe la respuesta, por favor ilumíneme: stackoverflow.com/questions/61726904/…
– Psicotecnópata
12 de mayo de 2020 a las 11:02
¿Existe una forma estándar integrada de hacer esto por columna sin recorrer todas las columnas?
– Gulzar
12 de enero de 2021 a las 10:42
hombre de arena
Puede usar 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 el scikit-learn documentación sobre el preprocesamiento de datos: escalar características a un rango.
Creo que esto eliminará los nombres de las columnas, lo que podría ser una de las razones por las que op está usando marcos de datos en primer lugar.
– pietz
16 de enero de 2017 a las 21:02
Esto normalizará las filas y no las columnas, a menos que lo transponga primero. Para hacer lo que pide la Q: pd.DataFrame(min_max_scaler.fit_transform(df.T), columns=df.columns, index=df.index)
– placas
20 de enero de 2017 a las 23:47
@pietz para mantener los nombres de las columnas, vea esta publicación. Básicamente reemplaza la última línea con , df=pandas.DataFrame(x_scaled, columns=df.columns)
– José
26 de junio de 2017 a las 18:52
@hobs Esto no es correcto. El código de Sandman se normaliza por columnas y por columnas. Obtienes un resultado incorrecto si transpones.
– petezurich
1 de abril de 2018 a las 14:10
@petezurich Parece que Sandman o Praveen corrigieron su código. Desafortunadamente, no es posible corregir los comentarios 😉
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 (Da estimaciones sesgadas, diferentes de pandas)
Si haces lo mismo con sklearn ¡Obtendrás una salida 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.preprocesamiento.escala establece que es POCO PROBABLE que el uso de un estimador sesgado afecte el rendimiento de los algoritmos de aprendizaje automático y que podemos usarlos de manera segura.
De la documentación oficial:
Usamos un estimador sesgado para la desviación estándar, equivalente a numpy.std(x, ddof=0). Tenga en cuenta que la elección de ddof es poco probable que afecte el rendimiento del modelo.
¿Qué pasa con el escalado MinMax?
No hay cálculo de Desviación estándar en el escalado 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
tschm
Su problema es en realidad una transformación simple que actúa sobre las columnas:
def f(s):
return s/s.max()
frame.apply(f, axis=0)
O aún más conciso:
frame.apply(lambda x: x/x.max(), axis=0)
los lambda uno es el mejor 🙂
– Abu Shoeb
8 dic 2018 a las 23:49
¿No se supone que esto es eje = 1 ya que la pregunta es la normalización de columnas?
– Nguai al
26 de abril de 2019 a las 23:27
no, de la documentos: axis [...] 0 or 'index': apply function to each column. El valor predeterminado es en realidad axis=0 así que esta frase se puede escribir aún más corta 🙂 Gracias @tschm.
– jorijnsmit
11 de abril de 2020 a las 15:01
Esto solo es correcto si el mínimo es 0, que no es algo que realmente deba asumir
– QFSW
21 de noviembre de 2020 a las 17:19
Mi ejemplo estaba destinado a ilustrar cómo aplicar funciones en columnas de marcos de datos. Obviamente, como siempre, debe prestar atención a los casos extremos, por ejemplo, aquí el máximo podría ser cero y generar un problema. No estoy seguro de entender @QFSW.
– tschm
22 de noviembre de 2020 a las 18:28
j triste
Si le gusta usar el paquete sklearn, puede mantener los nombres de columna e índice usando pandas loc al igual que:
¿No se supone que esto es eje = 1 ya que la pregunta es la normalización de columnas?
– Nguai al
26 de abril de 2019 a las 23:27
no, de la documentos: axis [...] 0 or 'index': apply function to each column. El valor predeterminado es en realidad axis=0 así que esta frase se puede escribir aún más corta 🙂 Gracias @tschm.
– jorijnsmit
11 de abril de 2020 a las 15:01
Esto solo es correcto si el mínimo es 0, que no es algo que realmente deba asumir
– QFSW
21 de noviembre de 2020 a las 17:19
Mi ejemplo estaba destinado a ilustrar cómo aplicar funciones en columnas de marcos de datos. Obviamente, como siempre, debe prestar atención a los casos extremos, por ejemplo, aquí el máximo podría ser cero y generar un problema. No estoy seguro de entender @QFSW.
– tschm
22 de noviembre de 2020 a las 18:28
gulzar
cuidado con esta respuestaya que SOLO funciona para datos que varían [0, n]. Esto no funciona para ningún rango de datos.
Tenga en cuenta que OP pidió [0..1] rango y esta solución escala a [-1..1] rango. Prueba esto con la matriz [-10, 10].
– Alexander Sosnovshchenko
28 de abril de 2018 a las 9:20
@AlexanderSosnovshchenko no realmente. Basil Musa asume que la matriz del OP siempre es no negativa, por eso ha dado esta solución. Si alguna columna tiene una entrada negativa, este código NO se normaliza a la [-1,1] rango. Pruébalo con la matriz [-5, 10]. La forma correcta de normalizar a [0,1] con valores negativos fue dado por la respuesta de Cina df["A"] = (df["A"]-df["A"].min()) / (df["A"].max()-df["A"].min())
– Pepe Mandioca
9 de noviembre de 2018 a las 13:24
Quizás incluso más simple: df /= df.max() – suponiendo que el objetivo es normalizar todas y cada una de las columnas, individualmente.
– n1k31t4
31 de mayo de 2020 a las 22:26
Esta respuesta es incorrecta. La suposición no negativa no se puede hacer aquí, ya que no es el OP ni los futuros lectores lo afirmaron. Además, incluso estrictamente positivo no funciona aquí: [1, 10] se normalizará a [0.1, 1] en vez de [0,1].
– Gulzar
12 de mayo de 2021 a las 11:53
Gracias @Gulzar, soy el autor de esta respuesta y, sinceramente, me sorprendió que se votara 29 veces.
– Albahaca Musa
18 mayo 2021 a las 15:12
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información
hay una función de aplicación, por ejemplo, frame.apply(f, axis=1) donde f es una función que hace algo con una fila…
– tschm
16/10/2014 a las 22:30
La normalización podría no ser la redacción más adecuada, ya que documentación de scikit-learn lo define como “el proceso de escalar muestras individuales para tener una norma unitaria” (es decir, fila por fila, si lo entiendo correctamente).
– Skippy el Gran Gourou
5 de marzo de 2019 a las 16:58
No lo entiendo, ¿por qué la escala min_max se considera normalización? normal tiene que tener significado en el sentido de distribución normal con media cero y varianza 1.
– Policía de desbordamiento
21 de abril de 2019 a las 2:21
Si está visitando esta pregunta en 2020 o posterior, mire la respuesta de @Poudel, obtendrá una respuesta diferente de normalización si usa pandas vs sklearn.
– BhishanPoudel
29 de enero de 2020 a las 20:10
@Poudel es esto debido a la
ddof
¿argumento?– escarcha
4 abr 2020 a las 20:26