Suma pandy według grupowania, ale wyklucz niektóre kolumny


88

Jaki jest najlepszy sposób wykonania grupowania w ramce danych Pandas, ale wykluczyć niektóre kolumny z tej grupy? np. mam następującą ramkę danych:

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ę pogrupować według kolumn Country i Item_Code i obliczyć tylko sumę wierszy należących do kolumn Y1961, Y1962 i Y1963. Wynikowa ramka danych 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 robię to:

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

Jednak sumuje to również wartości w kolumnie Item_Code. Czy istnieje sposób, w jaki mogę określić, które kolumny należy uwzględnić w sum()operacji, a które wykluczyć?

Odpowiedzi:


117

Możesz wybrać kolumny grupy według:

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

Zauważ, że przekazana lista musi być podzbiorem kolumn, w przeciwnym razie zobaczysz KeyError.


1
Jak uwzględnić liczbę rekordów dla każdego kraju i kodu towaru w innej kolumnie?
— Sushant Kulkarni

Możesz utworzyć fikcyjną kolumnę przed grupowaniem, która zawiera tylko 1, a następnie suma zsumuje te, tworząc liczbę.
— Matt W.,

Jeśli chcesz tylko wykluczyć jedną lub dwie kolumny, otrzymujesz wszystkie nazwy kolumn, tak jak w, listColumns = list(df.columns)a następnie usuwasz kolumny, których nie chcesz, listColumns.remove('Y1964')i na koniec wykonaj podsumowanie:df.groupby(['Country', 'Item_Code'])[listColumns].sum()
— Roberto Stelling

Wielkie dzięki. Mogę zmusić grupę do pracy, ale nie część dotyczącą wyboru. Lista kolumn, które umieściłem, znajduje się w ramce danych, ale wciąż podnosi wartość ValueError:cannot reindex from a duplicate axis
— Bowen Liu

@BowenLiu, jeśli masz wiele kolumn o tej samej nazwie, wyświetli ten błąd. W takim przypadku będziesz musiał użyć iloc do lub loc, aby uzyskać żądane kolumny, myślę, że będziesz musiał to zrobić przed grupowaniem.
— Andy Hayden

40

aggFunkcja zrobi to za Ciebie. Przekaż kolumny i działaj jako dykt z kolumną, 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

Spowoduje to wyświetlenie tylko grupy według kolumn i określonych kolumn zagregowanych. W tym przykładzie zawarłem dwie funkcje agowe zastosowane do „Y1962”.

Aby uzyskać dokładnie to, co chciałeś zobaczyć, uwzględnij inne kolumny w grupie według i zastosuj sumy 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})

1
dzięki, czy można to uogólnić? Mam wiele kolumn w formacie Y1961 ... więc generuję taką listę: yrs = ['Y' + str (x) for x in range (1961, 2010 + 1, 1)]. Czy Twoje rozwiązanie może wykorzystywać „rok” w środku agu?
— user308827

Naprawdę podoba mi się ten pomysł. Sztuczka polega na skonstruowaniu tego dyktu z wartością będącą funkcją numpy sum. I odwrotnie, jeśli wszystko, co chcesz zrobić, to zsumować wszystkie pozostałe kolumny, pierwotne rozwiązanie zadziałałoby, gdyby wszystkie kolumny grupuj według kolumn były zawarte w instrukcji grupuj według.
— leroyJr

11

Jeśli szukasz bardziej uogólnionego 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')
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.