2016-09-30 8 views
3

Ich habe ein Datenframe wo ich Groupby auf 3 Spalten und aggregieren die Summe und die Größe der numerischen Spalten. Nach dem Ausführen des CodesPandas: Erstellen Sie einzelne Größe und Summe Spalten nach der Gruppe von mehreren Spalten

df = pd.DataFrame.groupby(['year','cntry', 'state']).agg(['size','sum']) 

Ich bin immer so etwas wie unten:

Image of datafram

Jetzt möchte ich meine Größe Unter Spalten von Hauptspalten und erstellen Sie nur einzelne Größe Spalte spalten, sondern behalten wollen die Summenspalten unter Hauptspaltenüberschriften. Ich habe verschiedene Ansätze ausprobiert, aber nicht erfolgreich. Dies sind die Methoden, die ich versucht, aber nicht in der Lage, Dinge zu bekommen für mich arbeiten:

How to count number of rows in a group in pandas group by object?

Converting a Pandas GroupBy object to DataFrame

Wird dankbar, wenn jemand mir mit diesem helfen kann.

Grüße,

Antwort

4

Setup-

d1 = pd.DataFrame(dict(
     year=np.random.choice((2014, 2015, 2016), 100), 
     cntry=['United States' for _ in range(100)], 
     State=np.random.choice(states, 100), 
     Col1=np.random.randint(0, 20, 100), 
     Col2=np.random.randint(0, 20, 100), 
     Col3=np.random.randint(0, 20, 100), 
    )) 

df = d1.groupby(['year', 'cntry', 'State']).agg(['size', 'sum']) 
df 

enter image description here


Antwort
einfachste Weg, um nur Lauf gewesen wäre size nach groupby

d1.groupby(['year', 'cntry', 'State']).size() 

year cntry   State   
2014 United States California  10 
        Florida   9 
        Massachusetts  8 
        Minnesota   5 
2015 United States California  9 
        Florida   7 
        Massachusetts  4 
        Minnesota  11 
2016 United States California  8 
        Florida   8 
        Massachusetts 11 
        Minnesota  10 
dtype: int64 

Um die berechneten df

df.xs('size', axis=1, level=1) 

enter image description here

Und das wäre nützlich zu verwenden, wenn die size unterschiedlich waren für jede Spalte.Aber weil die size Spalte das gleiche für ['Col1', 'Col2', 'Col3'] ist, können wir tun, nur

df[('Col1', 'size')] 

year cntry   State   
2014 United States California  10 
        Florida   9 
        Massachusetts  8 
        Minnesota   5 
2015 United States California  9 
        Florida   7 
        Massachusetts  4 
        Minnesota  11 
2016 United States California  8 
        Florida   8 
        Massachusetts 11 
        Minnesota  10 
Name: (Col1, size), dtype: int64 

Kombinierte Ansicht 1

pd.concat([df[('Col1', 'size')].rename('size'), 
      df.xs('sum', axis=1, level=1)], axis=1) 

enter image description here


Kombinierte Ansicht 2

pd.concat([df[('Col1', 'size')].rename(('', 'size')), 
      df.xs('sum', axis=1, level=1, drop_level=False)], axis=1) 

enter image description here

+0

Hallo piRSquared, Danke für die ausführliche Antwort, aber ich habe zwei Anliegen mit dem Code oben. Erstens: Wenn ich den Code df.xs ('Größe', Achse = 1, Ebene = 1) Ich bekomme den folgenden Fehler: ValueError: Keine Achse namens 1 für den Objekttyp Zweitens muss ich die Summenspalten auch unter Spalte1, Spalte2 und Spalte3 behalten. Können Sie mir bitte sagen, wie ich das beheben kann? Grüße – Baig

+0

@Baig Der erste Wert Fehler, den Sie bekommen, ist von 'df' nicht ein Datenrahmen, sondern eine Reihe statt. Bitte überprüfen Sie Ihre Variablen. Wenn "d1" wie oben definiert ist und "df = d1.groupby (['year', 'cntry', 'State']). Agg (['size', 'sum'])' dann ist dieser Fehler unmöglich. Zweite Sorge, werde ich mit der Aktualisierung der Post ansprechen. – piRSquared

2

piRSquared schlug mich zu es aber, wenn Sie müssen es auf diese Weise tun und wollen, um die Ausrichtung mit den Säulen und die Summe oder die Größe zu halten, unter Ihnen die indizieren könnte Spalten, um den Größenwert zu entfernen, und fügen Sie dann eine neue Spalte hinzu, die den Größenwert enthält.

Zum Beispiel:

group = df.groupby(['year', 'cntry','state']).agg(['sum','size']) 
mi = pd.MultiIndex.from_product([['Col1','Col2','Col3'],['sum']]) 
group = group.reindex_axis(mi,axis=1) 
sizes = df.groupby('state').size().values 
group['Tot'] = 0 
group.columns = group.columns.set_levels(['sum','size'], level=1) 
group.Tot.size = sizes 

Es wird am Ende wie folgt suchen:

    Col1 Col2 Col3 Tot 
        sum sum sum size 
year cntry State 
2015 US CA  20 0 4 1 
      FL  40 3 5 1 
      MASS  8 1 3 1 
      MN  12 2 3 1 
Verwandte Themen