Ich habe einen Pandas-Datenrahmen mit gemischten Spalten und möchte den min_max_scaler von sklearn auf einige der Spalten anwenden. Im Idealfall würde ich diese Transformationen gerne an Ort und Stelle durchführen, habe aber noch keinen Weg gefunden, dies zu tun. Ich habe den folgenden Code geschrieben, der funktioniert:
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
Ich bin gespannt, ob dies der bevorzugte / effizienteste Weg ist, um diese Transformation durchzuführen. Gibt es eine Möglichkeit, wie ich df.apply verwenden könnte, die besser wäre?
Ich bin auch überrascht, dass ich den folgenden Code nicht zum Laufen bringen kann:
bad_output = min_max_scaler.fit_transform(dfTest['A'])
Wenn ich einen gesamten Datenrahmen an den Skalierer übergebe, funktioniert dies:
dfTest2 = dfTest.drop('C', axis = 1)
good_output = min_max_scaler.fit_transform(dfTest2)
good_output
Ich bin verwirrt, warum das Übergeben einer Serie an den Scaler fehlschlägt. In meinem obigen vollständigen Arbeitscode hatte ich gehofft, nur eine Reihe an den Skalierer zu übergeben und dann die Datenrahmenspalte = auf die skalierte Reihe zu setzen. Ich habe gesehen, dass diese Frage an einigen anderen Stellen gestellt wurde, aber keine gute Antwort gefunden. Jede Hilfe, um zu verstehen, was hier vor sich geht, wäre sehr dankbar!
quelle
bad_output = min_max_scaler.fit_transform(dfTest['A'].values)
? Der Zugriff auf dasvalues
Attribut gibt ein Numpy-Array zurück. Aus irgendeinem Grund ruft die Scikit-Lern-API manchmal die richtige Methode auf, mit der Pandas ein Numpy-Array zurückgibt, und manchmal nicht.bad_output = in_max_scaler.fit_transform(dfTest['A'].values)
hat auch nicht funktioniert. @larsmans - ja, ich hatte darüber nachgedacht, diesen Weg zu gehen, es scheint nur ein Ärger zu sein. Ich weiß nicht, ob es ein Fehler ist oder nicht, dass Pandas einen vollständigen Datenrahmen an eine sklearn-Funktion übergeben kann, aber keine Serie. Mein Verständnis eines Datenrahmens war, dass es sich um ein Diktat von Serien handelt. In dem Buch "Python for Data Analysis" heißt es, dass Pandas auf Numpy aufgebaut sind, um die Verwendung in NumPy-zentrierten Anwendungen zu vereinfachen.Antworten:
Ich bin nicht sicher, ob frühere Versionen dies
pandas
verhindert haben, aber jetzt funktioniert das folgende Snippet perfekt für mich und produziert genau das, was Sie wollen, ohne es verwenden zu müssenapply
quelle
df[df.columns] = scaler.fit_transform(df[df.columns])
__getitem__
Methode implementiert . Insbesondere können Sie Ihr Ipython öffnen und tunpd.DataFrame.__getitem__??
; nachdem du Pandas natürlich als pd importiert hast;)columns =df.columns.drop('timestamps') df[df.columns] = scaler.fit_transform(df[df.columns]
So was?
quelle
Wie in pirs Kommentar erwähnt, erzeugt die
.apply(lambda el: scale.fit_transform(el))
Methode die folgende Warnung:Das Konvertieren Ihrer Spalten in numpy-Arrays sollte den Job erledigen (ich bevorzuge StandardScaler):
- Edit Nov 2018 (Getestet auf Pandas 0.23.4 ) -Wie Rob Murray in den Kommentaren erwähnt,
.as_matrix()
kehrt Pandas in der aktuellen (v0.23.4) Version zurückFutureWarning
. Daher sollte es ersetzt werden durch.values
:- Bearbeiten Mai 2019 (Getestet auf Pandas 0.24.2 ) -
Wie Joelostblom in den Kommentaren erwähnt: "Da
0.24.0
wird empfohlen,.to_numpy()
anstelle von zu verwenden.values
."Aktualisiertes Beispiel:
quelle
.values
anstelle von.as_matrix()
wieas_matrix()
jetzt gibt einFutureWarning
.0.24.0
wird empfohlen,.to_numpy()
anstelle von zu verwenden.values
.Dies sollte ohne Abschreibungswarnungen funktionieren.
quelle
Sie können dies
pandas
nur tun mit :quelle
df.max() - df.min()
sie 0 sein kann, was zu einer Ausnahme führt. Darüber hinausdf.min()
wird zweimal berechnet, was ineffizient ist. Beachten Sie, dass diesdf.ptp()
äquivalent zu istdf.max() - df.min()
.Ich weiß, dass es ein sehr alter Kommentar ist, aber trotzdem:
Verwenden Sie anstelle einer einfachen Klammer
(dfTest['A'])
doppelte Klammern(dfTest[['A']])
.dh :
min_max_scaler.fit_transform(dfTest[['A']])
.Ich glaube, dies wird das gewünschte Ergebnis liefern.
quelle