2015-09-23 18 views
28

Cách tốt nhất để thực hiện một nhóm trên một 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ó foll. dataframe:Pandas tính theo nhóm, nhưng loại trừ các cột nhất định

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 các cột Quốc gia và Item_Code và chỉ tính tổng các hàng nằm dưới các cột Y1961, Y1962 và Y1963. Các dataframe kết quả sẽ giố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 cho biết thêm lên các giá trị trong cột Item_Code là tốt. Có cách nào tôi có thể chỉ định các cột để bao gồm trong hoạt động tổng() và những cột để loại trừ?

Trả lời

47

Bạn có thể chọn các cột của một 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 

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

+1

Làm cách nào để bao gồm số lượng bản ghi cho mỗi quốc gia và mã mặt hàng làm cột khác? –

+0

Bạn có thể tạo một cột giả trước khi nhóm theo đó chỉ chứa 1. sau đó tổng sẽ tổng hợp những người tạo ra một số. –

+0

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

16

Chức năng agg sẽ thực hiện việc này cho bạn. Vượt qua các cột và chức nă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ột tổng hợp được chỉ định. Trong ví dụ này, tôi bao gồm hai hàm agg được áp dụng cho 'Y1962'.

Để có được chính xác những gì bạn mong đợi để xem, bao gồm các cột khác trong nhóm do, và áp dụng một khoản tiền để 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}) 
+0

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

+0

Tôi thực sự thích ý tưởng này. Bí quyết đang xây dựng dict này với giá trị là hàm tổng hợp gumpy. Ngược lại, nếu tất cả những gì bạn muốn làm là tổng hợp tất cả các cột còn lại, giải pháp gốc-ish 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

3

Nếu bạn đang tìm 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à tạo 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') 
Các vấn đề liên quan