2016-08-13 5 views
20

Ich arbeitete früher mit R und liebe wirklich das dplyr-Paket, das Sie leicht gruppieren und zusammenfassen können.dplyr zusammenfassen Äquivalent in Pandas

jedoch in Pandas, ich habe nicht ein Äquivalent von summarize sehen und hier ist, wie ich es in Python zu erreichen:

import pandas as pd 
data = pd.DataFrame(
    {'col1':[1,1,1,1,1,2,2,2,2,2], 
    'col2':[1,2,3,4,5,6,7,8,9,0], 
    'col3':[-1,-2,-3,-4,-5,-6,-7,-8,-9,0] 
    } 
) 
result = [] 
for k,v in data.groupby('col1'): 
    result.append([k, max(v['col2']), min(v['col3'])]) 
print pd.DataFrame(result, columns=['col1', 'col2_agg', 'col3_agg']) 

Es ist nicht nur sehr ausführlich, aber auch vielleicht nicht die meisten optimiert werden und effizient. (Ich habe eine for loop groupby Implementierung in groupby.agg umgeschrieben und die Leistungssteigerung war riesig).

In R wird der Code

data %>% groupby(col1) %>% summarize(col2_agg=max(col2), col3_agg=min(col3)) 

Gibt es eine effiziente Äquivalent in Python oder für Schleife ist das, was ich mit zu arbeiten.


auch, @ayhan wirklich eine Lösung für meine Antwort gab, ist dies eine weitere Frage, die ich hier anstelle des Kommentars auflistet:

was ist das Äquivalent von groupby().summarize(newcolumn=max(col2 * col3))

+2

Sie können prüfen, [hier] (http: // pythonhosted.org/pandas-ply/) – akrun

Antwort

29

das Äquivalent von

df %>% groupby(col1) %>% summarize(col2_agg=max(col2), col3_agg=min(col3)) 

ist

df.groupby('col1').agg({'col2': 'max', 'col3': 'min'}) 

die

 col2 col3 
col1    
1  5 -5 
2  9 -9 

Die Rückkehr Objekt zurückgibt, ist ein pandas.DataFrame mit einem Index col1 und Spalten mit den Namen col2 und col3 genannt. Wenn Sie Ihre Daten gruppieren, legt Pandas standardmäßig die Gruppierungsspalte als Index für effizienten Zugriff und Änderung fest. Wenn Sie dies jedoch nicht möchten, gibt es zwei Alternativen, um col1 als Spalte festzulegen.

  • Pass as_index=False:

    df.groupby('col1', as_index=False).agg({'col2': 'max', 'col3': 'min'}) 
    
  • Anruf reset_index:

    df.groupby('col1').agg({'col2': 'max', 'col3': 'min'}).reset_index() 
    

sowohl Ausbeute als

col1 col2 col3   
    1  5 -5 
    2  9 -9 

Sie können auch mehrere Funktionen an groupby.agg übergeben.

agg_df = df.groupby('col1').agg({'col2': ['max', 'min', 'std'], 
           'col3': ['size', 'std', 'mean', 'max']}) 

Dies gibt auch einen DataFrame zurück, aber jetzt hat es einen MultiIndex für Spalten.

 col2    col3     
     max min  std size  std mean max 
col1           
1  5 1 1.581139 5 1.581139 -3 -1 
2  9 0 3.535534 5 3.535534 -6 0 

MultiIndex ist sehr praktisch für die Auswahl und Gruppierung.Hier sind einige Beispiele:

agg_df['col2'] # select the second column 
     max min  std 
col1      
1  5 1 1.581139 
2  9 0 3.535534 

agg_df[('col2', 'max')] # select the maximum of the second column 
Out: 
col1 
1 5 
2 9 
Name: (col2, max), dtype: int64 

agg_df.xs('max', axis=1, level=1) # select the maximum of all columns 
Out: 
     col2 col3 
col1    
1  5 -1 
2  9  0 

Früher (vor version 0.20.0) war es möglich, Wörterbücher zu verwenden, um die Spalten in dem agg Aufruf umbenennen. Zum Beispiel

df.groupby('col1')['col2'].agg({'max_col2': 'max'}) 

würde das Maximum der zweiten Spalte als max_col2 zurück:

 max_col2 
col1   
1   5 
2   9 

Es wurde jedoch zugunsten der Umbenennungs Methode veraltet:

df.groupby('col1')['col2'].agg(['max']).rename(columns={'max': 'col2_max'}) 

     col2_max 
col1   
1   5 
2   9 

Es kann ausführliche erhalten für einen Datenrahmen wie agg_df wie oben definiert. Sie können eine Umbenennung Funktion verwenden, um diese Ebene in diesem Fall zu glätten:

agg_df.columns = ['_'.join(col) for col in agg_df.columns] 

     col2_max col2_min col2_std col3_size col3_std col3_mean col3_max 
col1                   
1   5   1 1.581139   5 1.581139   -3  -1 
2   9   0 3.535534   5 3.535534   -6   0 

Für Operationen wie groupby().summarize(newcolumn=max(col2 * col3)), können Sie immer noch von ersten agg verwenden, um eine neue Spalte mit assign hinzufügen.

Dies gibt das Maximum für alte und neue Spalten zurück, aber wie immer können Sie das schneiden.

df.assign(new_col=df.eval('col2 * col3')).groupby('col1')['new_col'].agg('max') 

col1 
1 -1 
2 0 
Name: new_col, dtype: int64 

Mit groupby.apply würde dies kürzer sein:

df.groupby('col1').apply(lambda x: (x.col2 * x.col3).max()) 

col1 
1 -1 
2 0 
dtype: int64 

jedoch groupby.apply behandelt dies als eine benutzerdefinierte Funktion, so ist es nicht vektorisiert. Bisher wurden die Funktionen, die wir an agg ('min', 'max', 'min', 'size' usw.) übergeben haben, vektorisiert und diese sind Aliasnamen für diese optimierten Funktionen. Sie können df.groupby('col1').agg('min') durch df.groupby('col1').agg(min), df.groupby('col1').agg(np.min) oder df.groupby('col1').min() ersetzen und sie werden alle die gleiche Funktion ausführen. Sie werden nicht die gleiche Effizienz sehen, wenn Sie benutzerdefinierte Funktionen verwenden.

Zuletzt kann ab Version 0.20 agg direkt auf DataFrames verwendet werden, ohne dass zuerst gruppiert werden muss. Siehe Beispiele here.

+0

ich schätze wirklich die Antwort, vielleicht eine weitere Frage, 'agg ('col2': {'col2_max': max})' 'ist irgendwie komisch zu sagen' summieren (col2_max = ma x (col2)) '? Ich bin neugierig, was passiert, wenn ich mehrere Spalten verwende, also was ist das Äquivalent von 'summarize (result = max (col3 * col2))', Entschuldigung für wählerisch ... wirklich lohnt sich nicht die Mühe, ein zu fragen Neue Frage –

+0

Ja die Syntax ist ein wenig problematisch, das kommt häufig vor :) Agg funktioniert auch nur mit groupby Objekten. Sie können dies also nicht auf einen ganzen DataFrame anwenden. Stattdessen müssten Sie 'df ['col2']. Max()', 'df ['col3']. Min()' selbst kombinieren. Wenn Sie also versuchen, das Maximum von col3 * col2 zu finden, müssen Sie 'df ['col3'] * df ['col2']]) verwenden. Max()' Wenn Sie dies in einer Gruppe benötigen, müssen Sie dies zuerst tun Erstellen Sie eine Spalte: 'data.assign (col2_col3 = data ['col2'] * data ['col3']).groupby ('col1') ['col2_col3']. agg (max) ' – ayhan

+0

Die Kommentare in dieser Frage sind ebenfalls relevant: http://stackoverflow.com/questions/37209908/is-there-a-pandas-äquivalent-of -dplyrsummarise – ayhan

Verwandte Themen