Tổng số gấu trúc theo nhóm, nhưng loại trừ các cột nhất định


88

Cách tốt nhất để thực hiện phân nhóm trên khung dữ liệu Pandas, nhưng loại trừ một số cột khỏi nhóm đó là gì? ví dụ: tôi có khung dữ liệu sau:

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

Tôi muốn nhóm theo cột Quốc gia và Mã hàng và chỉ tính tổng các hàng nằm dưới các cột Y1961, Y1962 và Y1963. Khung dữ liệu kết quả sẽ trông như thế này:

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

Ngay bây giờ tôi đang làm điều này:

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

Tuy nhiên, điều này cũng làm tăng các giá trị trong cột Mã hàng. Có cách nào để tôi có thể chỉ định cột nào cần đưa vào sum()hoạt động và loại trừ cột nào không?

Câu trả lời:


117

Bạn có thể chọn các cột của một nhóm theo:

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

Lưu ý rằng danh sách được truyền phải là một tập hợp con của các cột, nếu không bạn sẽ thấy KeyError.


1
Làm thế nào để bao gồm số lượng bản ghi cho từng quốc gia và mã hàng dưới dạng một cột khác?
Sushant Kulkarni

Bạn có thể tạo một cột giả trước khi nhóm theo cột đó chỉ chứa 1. sau đó tổng sẽ tính tổng các cột đó tạo ra một số lượng.
Matt W.

Nếu bạn chỉ muốn loại trừ một hoặc hai cột, thì bạn sẽ nhận được tất cả các tên cột như trong listColumns = list(df.columns)đó, sau đó bạn loại bỏ các cột bạn không muốn listColumns.remove('Y1964')và cuối cùng thực hiện tổng kết của bạn:df.groupby(['Country', 'Item_Code'])[listColumns].sum()
Roberto Stelling

Cảm ơn rất nhiều. Tôi có thể khiến nhóm hoạt động, nhưng không phải phần lựa chọn. Danh sách các cột tôi đưa vào là một trong những dataframe, nhưng nó vẫn không ngừng nâng cao ValueError:cannot reindex from a duplicate axis
Bowen Liu

@BowenLiu nếu bạn có nhiều cột trùng tên, nó sẽ hiển thị lỗi này. Trong trường hợp này, bạn sẽ phải sử dụng iloc to hoặc loc để có được các cột bạn muốn, tôi nghĩ bạn sẽ phải làm điều đó trước khi nhóm.
Andy Hayden,

40

Các aggchức năng sẽ làm việc này cho bạn. Chuyển các cột và hoạt động như một dict với cột, đầu ra:

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

Điều này sẽ chỉ hiển thị nhóm theo cột và các cột tổng hợp được chỉ định. Trong ví dụ này, tôi bao gồm hai hàm tổng hợp được áp dụng cho 'Y1962'.

Để có được chính xác những gì bạn hy vọng sẽ thấy, hãy bao gồm các cột khác trong nhóm theo và áp dụng tổng cho các biến Y trong khung:

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

1
cảm ơn, điều này có thể được tổng quát? Tôi có rất nhiều cột có dạng Y1961 ... vì vậy tôi tạo một danh sách như sau: yrs = ['Y' + str (x) cho x trong phạm vi (1961, 2010 + 1, 1)]. Giải pháp của bạn có thể sử dụng 'yrs' bên trong agg không?
user308827

Tôi thực sự thích ý tưởng này. Bí quyết là xây dựng dict này với giá trị là hàm tổng numpy. Ngược lại, nếu tất cả những gì bạn muốn làm là tính tổng tất cả các cột còn lại, thì giải pháp ish ban đầu của bạn sẽ hoạt động nếu tất cả nhóm theo cột được bao gồm trong nhóm theo câu lệnh.
leroyJr

11

Nếu bạn đang tìm kiếm một cách tổng quát hơn để áp dụng cho nhiều cột, những gì bạn có thể làm là xây dựng danh sách tên cột và chuyển nó làm chỉ mục của khung dữ liệu được nhóm. Trong trường hợp của bạn, ví dụ:

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

df.groupby('Country')[columns].agg('sum')
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.