477 Stimmen

Normalisiere Spalten eines Dataframes

Ich habe einen DataFrame in Pandas, in dem jede Spalte einen unterschiedlichen Wertebereich hat. Zum Beispiel:

df:

A     B   C
1000  10  0.5
765   5   0.35
800   7   0.09

Irgendwelche Ideen, wie ich die Spalten dieses DataFrames normalisieren kann, so dass jeder Wert zwischen 0 und 1 liegt?

Meine gewünschte Ausgabe ist:

A     B    C
1     1    1
0.765 0.5  0.7
0.8   0.7  0.18 (was 0.09/0.5 entspricht)

816voto

Cina Punkte 9419

Ein einfacher Weg, um Pandas zu verwenden: (hier möchte ich die Mittelwertnormalisierung verwenden)

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

um die Min-Max-Normalisierung zu verwenden:

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

Bearbeiten: Um einige Bedenken anzusprechen, muss gesagt werden, dass Pandas automatisch die Funktionen spaltenweise im obigen code anwendet.

422voto

Sandman Punkte 5262

Sie können das Paket sklearn und seine zugehörigen Vorverarbeitungsdienstprogramme verwenden, um die Daten zu normalisieren.

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)

Weitere Informationen finden Sie in der scikit-learn Dokumentation zur Vorverarbeitung von Daten: Skalierung von Merkmalen auf einen Bereich.

89voto

BhishanPoudel Punkte 13129

Detailliertes Beispiel für Normalisierungsmethoden

  • Pandas-Normalisierung (unverzerrt)
  • Sklearn-Normalisierung (verzerrt)
  • Beeinflusst verzerrt vs. unverzerrt das maschinelle Lernen?
  • Mix-Max-Skalierung

Referenzen: Wikipedia: Unverzerrte Schätzung der Standardabweichung

Beispieldaten

import pandas as pd
df = pd.DataFrame({
               'A':[1,2,3],
               'B':[100,300,500],
               'C':list('abc')
             })
print(df)
   A    B  C
0  1  100  a
1  2  300  b
2  3  500  c

Normalisierung mit pandas (liefert unverzerrte Schätzungen)

Bei der Normalisierung subtrahieren wir einfach den Mittelwert und teilen durch die Standardabweichung.

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

Normalisierung mit sklearn (liefert verzerrte Schätzungen, unterschiedlich zu pandas)

Wenn Sie dasselbe mit sklearn machen, erhalten Sie eine ANDERE Ausgabe!

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

Beeinflussen verzerrte Schätzungen von sklearn die Leistung des maschinellen Lernens?

NEIN.

Die offizielle Dokumentation von sklearn.preprocessing.scale besagt, dass die Verwendung eines verzerrten Schätzers UNWAHRSCHEINLICH ist, die Leistung von maschinellen Lernalgorithmen zu beeinflussen und wir sie sicher verwenden können.

Aus der offiziellen Dokumentation:

Wir verwenden einen verzerrten Schätzer für die Standardabweichung, äquivalent zu numpy.std(x, ddof=0). Beachten Sie, dass die Wahl von ddof unwahrscheinlich ist, die Modellleistung zu beeinflussen.

Was ist mit MinMax-Skalierung?

Bei der MinMax-Skalierung wird keine Standardabweichung berechnet. Daher ist das Ergebnis sowohl in pandas als auch in scikit-learn gleich.

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

# Mit 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

79voto

Michael Aquilina Punkte 5022

Basierend auf diesem Beitrag: https://stats.stackexchange.com/questions/70801/how-to-normalize-data-to-0-1-range

Sie können Folgendes tun:

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

Sie müssen sich nicht darum kümmern, ob Ihre Werte negativ oder positiv sind. Und die Werte sollten schön zwischen 0 und 1 verteilt sein.

66voto

tschm Punkte 2905

Ihr Problem ist tatsächlich eine einfache Transformation, die auf den Spalten ausgeführt wird:

def f(s):
    return s/s.max()

frame.apply(f, axis=0)

Oder noch knapper:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X