les pandas dataframe colonnes de mise à l'échelle avec sklearn
J'ai une pandas dataframe avec un mélange de colonnes de type, et j'aimerais appliquer sklearn de min_max_scaler de certaines colonnes. Idéalement, j'aimerais faire ces transformations en place, mais n'avez pas trouvé un moyen de le faire encore. J'ai écrit le code suivant qui fonctionne:
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
Je suis curieux de savoir si c'est la meilleur/le plus efficace pour faire cette transformation. Est-il une manière que je pourrais utiliser df.appliquer ce serait mieux?
Je suis aussi surpris de voir que je ne peux pas avoir le code suivant fonctionne:
bad_output = min_max_scaler.fit_transform(dfTest['A'])
Si je passe tout un dataframe pour le scaler cela fonctionne:
dfTest2 = dfTest.drop('C', axis = 1)
good_output = min_max_scaler.fit_transform(dfTest2)
good_output
Je suis confus pourquoi le passage d'une série à l'écailleur échoue. Dans mon travail plein de code ci-dessus, j'espérais juste passer d'une série à l'écailleur puis définissez le dataframe colonne = à l'échelle de la série. J'ai vu cette question posée à quelques autres endroits, mais je n'ai pas trouvé une bonne réponse. Toute aide pour comprendre ce qui se passe ici serait grandement apprécié!
- Cela fonctionne si vous faites cela
bad_output = min_max_scaler.fit_transform(dfTest['A'].values)
? accéder à lavalues
attribut retourne un tableau numpy, pour quelque raison que parfois la scikit learn api correctement appeler la bonne méthode qui rend les pandas retourne un tableau numpy et parfois ça ne marche pas. - Des Pandas dataframes sont assez complexes, des objets avec des conventions qui ne correspondent pas à scikit-learn conventions. Si vous avez tout convertir des tableaux NumPy, scikit-learn devient beaucoup plus facile de travailler avec.
bad_output = in_max_scaler.fit_transform(dfTest['A'].values)
ne fonctionne pas non plus. @larsmans - ouais j'avais pensé à aller vers le bas de cette route, il semble juste comme une corvée. Je ne sais pas si c'est un bug ou pas que les Pandas pouvez passer en plein dataframe à un sklearn fonction, mais pas une série. Ma compréhension d'un dataframe est que c'est un dict de la série. À lire dans le "Python pour l'Analyse des Données" livre, il affirme que les pandas est construit sur le haut de numpy pour le rendre facile à utiliser dans NumPy centrée sur applicatations.
Vous devez vous connecter pour publier un commentaire.
Je ne sais pas si les versions précédentes de
pandas
empêché de cela, mais maintenant l'extrait de code suivant fonctionne parfaitement pour moi et produit exactement ce que vous voulez sans avoir à utiliserapply
df[df.columns] = scaler.fit_transform(df[df.columns])
__getitem__
méthode. Plus précisément, vous pouvez vous ouvrir ipython et nepd.DataFrame.__getitem__??
; après l'importation de pandas que le pd, bien sûr 😉scaler.fit()
etscaler.transform()
sur deux lignes distinctes, je reçois le redoutableSettingWithCopyWarning
. Quelqu'un a une idée pourquoi?df[df.columns] = scaler.fit_transform(df[df.columns])
- parfait @citynorman!columns =df.columns.drop('timestamps') df[df.columns] = scaler.fit_transform(df[df.columns]
Comme ça?
Comme il est mentionné dans le pir commentaire - la
.apply(lambda el: scale.fit_transform(el))
méthode génère le message d'avertissement suivant:La conversion de vos colonnes pour les tableaux numpy devrait faire l'affaire (je préfère StandardScaler):
-- Modifier Novembre 2018 (Testé pour les pandas 0.23.4)--De Rob Murray mentionne dans les commentaires, dans le courant (v0.23.4) la version de pandas
.as_matrix()
retourneFutureWarning
. Par conséquent, il doit être remplacé par.values
:-- Modifier Mai 2019 (Testé pour les pandas 0.24.2)--
Comme joelostblom mentionne dans les commentaires, "Depuis
0.24.0
, il est recommandé d'utiliser.to_numpy()
au lieu de.values
."Mis à jour exemple:
.values
en place de.as_matrix()
commeas_matrix()
donne maintenant unFutureWarning
.0.24.0
, il est recommandé d'utiliser.to_numpy()
au lieu de.values
..apply
?Vous pouvez le faire en utilisant
pandas
seulement:df.max() - df.min()
peut être 0, conduisant à une exception. En outre,df.min()
est calculée deux fois, ce qui est inefficace. Notez quedf.ptp()
est équivalent àdf.max() - df.min()
.Cela devrait fonctionner sans l'amortissement des avertissements.