2013-07-16 41 views
16

Tôi có python gấu trúc khung dữ liệu sau:python gấu trúc groupby() kết quả

df = pd.DataFrame({ 
    'A': [1,1,1,1,2,2,2,3,3,4,4,4], 
    'B': [5,5,6,7,5,6,6,7,7,6,7,7], 
    'C': [1,1,1,1,1,1,1,1,1,1,1,1] 
    }); 

df 
    A B C 
0 1 5 1 
1 1 5 1 
2 1 6 1 
3 1 7 1 
4 2 5 1 
5 2 6 1 
6 2 6 1 
7 3 7 1 
8 3 7 1 
9 4 6 1 
10 4 7 1 
11 4 7 1 

Tôi muốn có một cột lưu trữ một giá trị của một khoản tiền trên giá trị C cho cố định A (cả hai) và B. đó là, một cái gì đó như:

A B C D 
0 1 5 1 2 
1 1 5 1 2 
2 1 6 1 1 
3 1 7 1 1 
4 2 5 1 1 
5 2 6 1 2 
6 2 6 1 2 
7 3 7 1 2 
8 3 7 1 2 
9 4 6 1 1 
10 4 7 1 2 
11 4 7 1 2 

tôi đã thử với gấu trúc groupby và nó loại hoạt động:

res = {} 
for a, group_by_A in df.groupby('A'): 
    group_by_B = group_by_A.groupby('B', as_index = False) 
    res[a] = group_by_B['C'].sum() 

nhưng tôi không biết cách 'nhận' kết quả từ res thành df theo cách có trật tự. Sẽ rất hài lòng với bất kỳ lời khuyên nào về điều này. Cảm ơn bạn.

Trả lời

13

Đây là một cách (mặc dù nó cảm thấy điều này sẽ làm việc trong một lần với một áp dụng, tôi không thể có được nó).

In [11]: g = df.groupby(['A', 'B']) 

In [12]: df1 = df.set_index(['A', 'B']) 

Chức năng size groupby là một trong những bạn muốn, chúng tôi có để phù hợp với nó vào 'A' và 'B' như chỉ số:

In [13]: df1['D'] = g.size() # unfortunately this doesn't play nice with as_index=False 
# Same would work with g['C'].sum() 

In [14]: df1.reset_index() 
Out[14]: 
    A B C D 
0 1 5 1 2 
1 1 5 1 2 
2 1 6 1 1 
3 1 7 1 1 
4 2 5 1 1 
5 2 6 1 2 
6 2 6 1 2 
7 3 7 1 2 
8 3 7 1 2 
9 4 6 1 1 
10 4 7 1 2 
11 4 7 1 2 
+0

Cảm ơn bạn @Andy Hayden! Các giải pháp với 'tổng hợp 'là chung chung hơn tôi nghĩ. Trong thực tế, tôi không có '1' trong' C' (khi 'size' hoạt động hoàn hảo, như bạn đã chỉ ra trong giải pháp của bạn) nhưng thay vào đó là một số float, do đó, để làm cho công việc đó đúng, tôi cần phải đi với' sum'. Nhưng dù sao, rực rỡ, cảm ơn bạn một lần nữa. –

+4

Tôi nghĩ rằng một lớp lót bạn mơ ước là '' df ['D'] = df.groupby (['A', 'B']). Transform (np.size) ''. Trong thời điểm tốt và xấu, '' transform'' là ở đó. :-D –

6

Bạn cũng có thể làm một cái lót sử dụng hợp nhất như sau:

df = df.merge(pd.DataFrame({'D':df.groupby(['A', 'B'])['C'].size()}), left_on=['A', 'B'], right_index=True) 
+0

dễ đọc và dễ hiểu – jiamo

5

Bạn cũng có thể làm một cái lót sử dụng biến đổi áp dụng cho các groupby:

df['D'] = df.groupby(['A','B'])['C'].transform('sum') 
Các vấn đề liên quan