Pandas: Konvertieren Sie Kategorien in Zahlen

82

Angenommen, ich habe einen Datenrahmen mit Ländern, der wie folgt lautet:

cc | temp
US | 37.0
CA | 12.0
US | 35.0
AU | 20.0

Ich weiß, dass es eine pd.get_dummies-Funktion gibt, mit der die Länder in "One-Hot-Codierungen" konvertiert werden können. Ich möchte sie jedoch stattdessen in Indizes umwandeln, sodass ich sie cc_index = [1,2,1,3]stattdessen erhalte .

Ich gehe davon aus, dass es einen schnelleren Weg gibt als die Verwendung von get_dummies zusammen mit einer numpy where-Klausel, wie unten gezeigt:

[np.where(x) for x in df.cc.get_dummies().values]

Dies ist in R mit 'Faktoren' etwas einfacher, also hoffe ich, dass Pandas etwas Ähnliches haben.

Sachinruk
quelle
2
Meinst du cc_index = [0,1,0,2]?
juanpa.arrivillaga
1
sicher, vergessen über den Python 0 Index
Sachinruk
Kategoriale Reihen oder Spalten in einem DataFrame können hilfreich sein.
Min2bro

Antworten:

143

Ändern Sie zunächst den Typ der Spalte:

df.cc = pd.Categorical(df.cc)

Jetzt sehen die Daten ähnlich aus, werden aber kategorisch gespeichert. So erfassen Sie die Kategoriecodes:

df['code'] = df.cc.cat.codes

Jetzt hast du:

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0

Wenn Sie Ihren DataFrame nicht ändern möchten, sondern einfach die Codes erhalten möchten:

df.cc.astype('category').cat.codes

Oder verwenden Sie die kategoriale Spalte als Index:

df2 = pd.DataFrame(df.temp)
df2.index = pd.CategoricalIndex(df.cc)
John Zwinck
quelle
2
Der Anruf df.cc.cat.codesscheint sich auf gerade geändert zu haben df.cc.codes?
Andreas Storvik Strauman
Beachten Sie, dass fehlende Werte mit -1 codiert werden. Wenn Sie vermeiden möchten, diesen Fall zu behandeln, können Sie zuerst in einen String umwandeln: df.cc.astype ('str'). Astype ('category'). Cat.codes
Guy s
23

Wenn Sie Ihre Serie nur in ganzzahlige Bezeichner umwandeln möchten, können Sie verwenden pd.factorize.

Beachten Sie, dass diese Lösung im Gegensatz pd.Categoricaldazu nicht alphabetisch sortiert wird. So wird das erste Land zugewiesen 0. Wenn Sie beginnen möchten 1, können Sie eine Konstante hinzufügen:

df['code'] = pd.factorize(df['cc'])[0] + 1

print(df)

   cc  temp  code
0  US  37.0     1
1  CA  12.0     2
2  US  35.0     1
3  AU  20.0     3

Wenn Sie alphabetisch sortieren möchten, geben Sie Folgendes an sort=True:

df['code'] = pd.factorize(df['cc'], sort=True)[0] + 1 
jpp
quelle
11

Wenn Sie die sklearnBibliothek verwenden, können Sie verwenden LabelEncoder. Ebenso pd.Categoricalwerden Eingabezeichenfolgen vor dem Codieren alphabetisch sortiert.

from sklearn.preprocessing import LabelEncoder

LE = LabelEncoder()
df['code'] = LE.fit_transform(df['cc'])

print(df)

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0
jpp
quelle
2

Versuchen Sie dies, konvertieren Sie in eine Zahl basierend auf der Frequenz (Hochfrequenz - hohe Zahl):

labels = df[col].value_counts(ascending=True).index.tolist()
codes = range(1,len(labels)+1)
df[col].replace(labels,codes,inplace=True)
Palepalli Surendra Reddy
quelle
1

Ändert alle Spalten in Zahlen. Es wird keine neue Spalte erstellt, sondern nur die Werte durch numerische Daten ersetzt.

def characters_to_numb(*args): for arg in args: df[arg] = pd.Categorical(df[arg]) df[arg] = df[arg].cat.codes return df

Denis Kalyan
quelle
0

Einzeiliger Code:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes)

Dies funktioniert auch, wenn Sie eine list_of_columns:

df[list_of_columns] = df[list_of_columns].apply(lambda col:pd.Categorical(col).codes)

Wenn Sie Ihre NaNWerte beibehalten möchten, können Sie außerdem Folgendes ersetzen:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes).replace(-1,np.nan)
Piotro
quelle