2016-05-23 12 views
1

Da ich einen Datenrahmen mit einer Spalte, die Listen von Zeichenketten enthält, wie folgt aus:get_dummies für Pandas Spaltenliste enthält

Name Fruit 
0 Curly [Apple] 
1 Moe  [Orange] 
2 Larry [Apple, Banana] 

Wie würde ich wiederum, dass in so etwas wie das?

Name  Fruit_Apple Fruit_Orange Fruit_Banana 
0 Curly    1    0    0 
1 Moe    0    1    0 
2 Larry    1    0    1 

Ich habe ein Gefühl, das ich irgendwie pandas.get_dummies() verwenden würde, aber ich kann nicht um es zu bekommen scheinen. Irgendeine Hilfe?

Antwort

5
import pandas as pd 

df = pd.DataFrame({'Name': ['Curly', 'Moe', 'Larry'], 
        'Fruit': [['Apple'], ['Orange'], ['Apple', 'Banana']]}, 
        columns=['Name', 'Fruit']) 

# a one-liner... that's pretty long  
dummies_df = pd.get_dummies(
    df.join(pd.Series(df['Fruit'].apply(pd.Series).stack().reset_index(1, drop=True), 
        name='Fruit1')).drop('Fruit', axis=1).rename(columns={'Fruit1': 'Fruit'}), 
    columns=['Fruit']).groupby('Name', as_index=False).sum() 

print(dummies_df) 

Ich werde diese brechen in Stufen hinunter:

Schritt 1:

df['Fruit'].apply(pd.Series).stack().reset_index(1, drop=True)

Dieser Schritt gilt pd.Series auf Ihre Listen, die jedes Element in den Listen ein Spagat neue Spalte. stack stapelt diese Spalten dann in eine einzelne Spalte, während wichtige Indexinformationen beibehalten werden. Der reset_index Teil setzt Level 1 des Index zurück und lässt ihn fallen, weil er nicht benötigt wird. Sie am Ende mit diesem:

0  Apple 
1 Orange 
2  Apple 
2 Banana 
dtype: object 

Schritt 2:

Sie pd.Series(*Step 1 here*, name='Fruit1') gewickelt ist oben um Schritt 1 Code auffallen werden, weil ich neben dieser Serie zu dem bestehenden Datenrahmen verbinden, so brauchen wir ein name um das zu tun.

Schritt 3:

df.join(* steps 1 and 2 code *).drop('Fruit', axis=1).rename(columns={'Fruit1': 'Fruit'}) 

Da wir nun einen pd.Series mit einem Namen (Fruit1) haben, verbinden wir die Fruit1 Serie auf den ursprünglichen df, die dann drei Spalten. Wir rufen dann Drop to Drop die ursprüngliche Fruit Spalte. Jetzt haben wir nur zwei Spalten Name und Fruit1, aber wir wollen Fruit heißen Fruit, also benennen wir es mit rename um.

Schritt 4:

pd.get_dummies(* steps 1, 2, and 3 here*, columns=['Fruit']) 

Hier rufen wir schließlich die get_dummies und wir nutzen die columns=['Fruit'] speziell get_dummies zu sagen, nur Attrappen für die Fruchtsäule zu erhalten.

Name Fruit_Apple Fruit_Banana Fruit_Orange 
0 Curly   1.0   0.0   0.0 
1 Moe   0.0   0.0   1.0 
2 Larry   1.0   0.0   0.0 
2 Larry   0.0   1.0   0.0 

Schritt 5:

dummies_df = (*steps 1, 2, 3, and 4*).groupby('Name', as_index=False).sum() 

Schließlich verwenden Sie eine groupby auf der Name Spalte und geben Sie as_index=False nicht optional die Name als Index gesetzt.Dann Summe, die zur Folge haben mit .sum()

Endergebnis:

Name Fruit_Apple Fruit_Banana Fruit_Orange 
0 Curly   1.0   0.0   0.0 
1 Larry   1.0   1.0   0.0 
2 Moe   0.0   0.0   1.0 
+2

Sie können Schritt 4 und 5 mit pd.crosstab (df_unwind [ 'Name'], df_unwind [ 'Fruit1']) ersetzen. df_unwind ist der df nach Schritt 3. Sie ist nicht einzeilig, sondern kürzer. – knagaev

Verwandte Themen