Jumlah panda menurut groupby, tetapi mengecualikan kolom tertentu

89

Apa cara terbaik untuk melakukan groupby pada dataframe Pandas, tapi mengecualikan beberapa kolom dari groupby itu? misalnya saya memiliki dataframe berikut:

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

Saya ingin mengelompokkan berdasarkan kolom Country dan Item_Code dan hanya menghitung jumlah baris yang berada di bawah kolom Y1961, Y1962 dan Y1963. Dataframe yang dihasilkan akan terlihat seperti ini:

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

Sekarang saya melakukan ini:

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

Namun ini menambahkan nilai di kolom Item_Code juga. Adakah cara untuk menentukan kolom mana yang akan disertakan dalam sum()operasi dan mana yang akan dikecualikan?

pengguna308827
sumber

Jawaban:

120

Anda dapat memilih kolom grup dengan:

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

Perhatikan bahwa daftar yang diteruskan harus merupakan subset dari kolom jika tidak, Anda akan melihat KeyError.

Andy Hayden
sumber
1
Bagaimana cara memasukkan hitungan catatan untuk setiap negara & kode item sebagai kolom lain?
Sushant Kulkarni
Anda dapat membuat kolom dummy sebelum mengelompokkan dengan yang hanya berisi 1. lalu jumlah akan menjumlahkan semua itu sehingga membuat hitungan.
Matt W.
Jika Anda hanya ingin mengecualikan satu atau dua kolom, maka Anda mendapatkan semua nama kolom seperti listColumns = list(df.columns)kemudian Anda menghapus kolom yang tidak Anda inginkan, listColumns.remove('Y1964')dan akhirnya lakukan penjumlahan Anda:df.groupby(['Country', 'Item_Code'])[listColumns].sum()
Roberto Stelling
Terima kasih banyak. Saya bisa membuat grup bekerja, tetapi bukan bagian seleksi. Daftar kolom yang saya masukkan ada di antara dataframe, tetapi terus meningkatkan ValueError:cannot reindex from a duplicate axis
Bowen Liu
@BowenLiu jika Anda memiliki beberapa kolom dengan nama yang sama itu akan menampilkan kesalahan ini. Dalam hal ini Anda harus menggunakan iloc to atau loc untuk mendapatkan kolom yang Anda inginkan, saya pikir Anda harus melakukannya sebelum groupby.
Andy Hayden
40

The aggfungsi akan melakukan ini untuk Anda. Teruskan kolom dan fungsi sebagai dikt dengan kolom, keluaran:

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

Ini hanya akan menampilkan grup menurut kolom, dan kolom agregat yang ditentukan. Dalam contoh ini saya menyertakan dua fungsi agg yang diterapkan ke 'Y1962'.

Untuk mendapatkan apa yang Anda harapkan untuk dilihat, sertakan kolom lain di grup dengan, dan terapkan jumlah ke variabel Y dalam bingkai:

df.groupby(['Code', 'Country', 'Item_Code', 'Item', 'Ele_Code', 'Unit']).agg({'Y1961': np.sum, 'Y1962': np.sum, 'Y1963': np.sum})
leroyJr
sumber
1
terima kasih, apakah ini bisa digeneralisasikan? Saya memiliki banyak kolom dalam bentuk Y1961 ... jadi saya membuat daftar seperti ini: yrs = ['Y' + str (x) untuk x dalam rentang (1961, 2010 + 1, 1)]. Dapatkah solusi Anda menggunakan 'yrs' inside agg?
pengguna308827
Saya sangat menyukai ide ini. Triknya adalah membuat dikt ini dengan nilai yang menjadi fungsi jumlah numpy. Sebaliknya, jika yang ingin Anda lakukan hanyalah menjumlahkan semua kolom yang tersisa, solusi original-ish Anda akan berfungsi jika semua grup menurut kolom disertakan dalam grup dengan pernyataan.
leroyJr
11

Jika Anda mencari cara yang lebih umum untuk diterapkan ke banyak kolom, yang dapat Anda lakukan adalah membuat daftar nama kolom dan meneruskannya sebagai indeks kerangka data yang dikelompokkan. Dalam kasus Anda, misalnya:

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

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