Tengo un dataframe Pandas ‘df’ en el que me gustaría realizar algunas escalas columna por columna.
¿Hay una función de Pandas para realizar estas dos operaciones? Si no, Numpy sin duda lo haría.
ab A 14 103 B 90 107 C 90 110 D 96 114 E 91 114
Podrías restar por el mínimo, luego dividir por el máximo (cuidado 0/0). Tenga en cuenta que después de restar el mínimo, el nuevo máximo es el máximo original – mín.
In [11]: df Out[11]: ab A 14 103 B 90 107 C 90 110 D 96 114 E 91 114 In [12]: df -= df.min() # equivalent to df = df - df.min() In [13]: df /= df.max() # equivalent to df = df / df.max() In [14]: df Out[14]: ab A 0.000000 0.000000 B 0.926829 0.363636 C 0.926829 0.636364 D 1.000000 1.000000 E 0.939024 1.000000
Para cambiar el orden de una columna (de 1 a 0 en lugar de 0 a 1):
In [15]: df['b'] = 1 - df['b']
Un método alternativo es negar las columnas b primero ( df['b'] = -df['b']
).
Así es como puedes hacerlo usando sklearn
y el módulo de preprocessing
. Sci-Kit Learn tiene muchas funciones de preprocesamiento para escalar y centrar datos.
In [0]: from sklearn.preprocessing import MinMaxScaler In [1]: df = pd.DataFrame({'A':[14,90,90,96,91], 'B':[103,107,110,114,114]}).astype(float) In [2]: df Out[2]: AB 0 14 103 1 90 107 2 90 110 3 96 114 4 91 114 In [3]: scaler = MinMaxScaler() In [4]: df_scaled = pd.DataFrame(scaler.fit_transform(df), columns=df.columns) In [5]: df_scaled Out[5]: AB 0 0.000000 0.000000 1 0.926829 0.363636 2 0.926829 0.636364 3 1.000000 1.000000 4 0.939024 1.000000
Esto no es muy elegante, pero lo siguiente funciona para este caso de dos columnas:
#Create dataframe df = pd.DataFrame({'A':[14,90,90,96,91], 'B':[103,107,110,114,114]}) #Apply operates on each row or column with the lambda function #axis = 0 -> act on columns, axis = 1 act on rows #x is a variable for the whole row or column #This line will scale minimum = 0 and maximum = 1 for each column df2 = df.apply(lambda x:(x.astype(float) - min(x))/(max(x)-min(x)), axis = 0) #Want to now invert the order on column 'B' #Use apply function again, reverse numbers in column, select column 'B' only and #reassign to column 'B' of original dataframe df2['B'] = df2.apply(lambda x: 1-x, axis = 1)['B']
Si encuentro una forma más elegante (por ejemplo, usando el índice de la columna: (0 o 1) mod 2 – 1 para seleccionar el signo en la operación de aplicación para que se pueda hacer con un solo comando de aplicación, le avisaré) .
En caso de que desee escalar solo una columna en el dataframe, puede hacer lo siguiente:
from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() df['Col1_scaled'] = scaler.fit_transform(df['Col1'].values.reshape(-1,1))
dado un dataframe
df = pd.DataFrame({'A':[14,90,90,96,91], 'B':[103,107,110,114,114]})
escala con media 0 y var 1
df.apply(lambda x: (x - np.mean(x)) / np.std(x), axis=0)
escala con rango entre 0 y 1
df.apply(lambda x: x / np.max(x), axis=0)