2015-09-23 17 views
28

Jaki jest najlepszy sposób, aby zrobić groupby na ramce danych Pandy, ale wykluczyć niektóre kolumny z tej grupy? Na przykład. Mam foll. dataframe:Panda suma przez groupby, ale wykluczyć niektóre kolumny

Code Country Item_Code Item Ele_Code Unit Y1961 Y1962 Y1963 
2 Afghanistan 15   Wheat 5312  Ha  10  20  30 
2 Afghanistan 25   Maize 5312  Ha  10  20  30 
4 Angola  15   Wheat 7312  Ha  30  40  50 
4 Angola  25   Maize 7312  Ha  30  40  50 

Chcę GroupBy Kraju kolumny i Item_Code i tylko obliczyć sumę wierszy objętych kolumn Y1961, Y1962 i Y1963. Powstały dataframe powinna wyglądać następująco:

Code Country Item_Code Item Ele_Code Unit Y1961 Y1962 Y1963 
    2 Afghanistan 15  C3  5312  Ha  20  40  60 
    4 Angola  25  C4  7312  Ha  60  80  100 

Teraz robie to:

df.groupby('Country').sum() 

Jednak ta sumuje wartości w kolumnie Item_Code również. Czy jest jakiś sposób mogę określić, które kolumny należy uwzględnić w operacji sum() i które należy wyłączyć?

Odpowiedz

47

można wybrać kolumny o GroupBy:

In [11]: df.groupby(['Country', 'Item_Code'])[["Y1961", "Y1962", "Y1963"]].sum() 
Out[11]: 
         Y1961 Y1962 Y1963 
Country  Item_Code 
Afghanistan 15   10  20  30 
      25   10  20  30 
Angola  15   30  40  50 
      25   30  40  50 

Należy zauważyć, że przekazana lista musi być podzestawem kolumn, w przeciwnym razie pojawi się błąd KeyError.

+1

Jak uwzględnić liczbę rekordów dla każdego kraju i kodu przedmiotu jako kolejną kolumnę? –

+0

Można utworzyć atrapę kolumny przed grupowaniem przez to, że zawiera 1. wtedy suma będzie sumować je tworząc licznik. –

+0

Jeśli chcesz tylko wykluczyć kolumnę lub dwie, otrzymasz wszystkie nazwy kolumn jak na liście 'listColumns = list (df.columns)', a następnie usuniesz kolumny, których nie chcesz, 'listColumns.remove ('Y1964') 'i wreszcie wykonaj twoje sumowanie:' df.groupby (['Country', 'Item_Code']) [listColumns] .sum() ' –

16

Funkcja agg zrobi to za Ciebie. Kolumny i przekazać funkcję jako dict z kolumny, Wyjście:

df.groupby(['Country', 'Item_Code']).agg({'Y1961': np.sum, 'Y1962': [np.sum, np.mean]}) # Added example for two output columns from a single input column 

To spowoduje wyświetlenie tylko grupa kolumnami, a określonych kolumnach kruszywa. W tym przykładzie zawarłem dwie funkcje agg zastosowane do "Y1962".

Aby dostać dokładnie to, czego spodziewał się zobaczyć, zawarte innych kolumn w grupie przez i zastosować sum do zmiennych Y w ramce:

df.groupby(['Code', 'Country', 'Item_Code', 'Item', 'Ele_Code', 'Unit']).agg({'Y1961': np.sum, 'Y1962': np.sum, 'Y1963': np.sum}) 
+0

dzięki, czy można to uogólnić? Mam wiele kolumn formularza Y1961 ... więc generuję listę taką jak ta: yrs = ['Y' + str (x) dla x w zakresie (1961, 2010 + 1, 1)]. Czy Twoje rozwiązanie może wykorzystywać "lat" wewnątrz ag? – user308827

+0

Bardzo podoba mi się ten pomysł. Sztuczka polega na konstruowaniu tego dyktatu, którego wartością jest funkcja numpy sum. I odwrotnie, jeśli wszystko, co chcesz zrobić, to zsumować wszystkie pozostałe kolumny, oryginalne rozwiązanie będzie działać, jeśli wszystkie grupy według kolumn są zawarte w grupie według instrukcji. – leroyJr

3

Jeśli szukasz bardziej ogólnego sposobu zastosowania do wielu kolumn, możesz utworzyć listę nazw kolumn i przekazać ją jako indeks zgrupowanej ramki danych. W twoim przypadku, na przykład:

columns = ['Y'+str(i) for year in range(1967, 2011)] 

df.groupby('Country')[columns].agg('sum')