2013-03-06 39 views
12

Tôi vừa mới thực hiện chuyển đổi từ R sang python và đã gặp phải một số sự cố khi sử dụng lại khung dữ liệu thay vì sử dụng data.table của R. Vấn đề tôi gặp phải là tôi muốn lấy danh sách các chuỗi, kiểm tra một giá trị, sau đó tính tổng số chuỗi đó được chia nhỏ bởi người dùng. Vì vậy, tôi muốn lấy dữ liệu này:khoản tiền điều kiện cho tổng hợp gấu trúc

A_id  B C 
1: a1 "up" 100 
2: a2 "down" 102 
3: a3 "up" 100 
3: a3 "up" 250 
4: a4 "left" 100 
5: a5 "right" 102 

Và trở lại:

A_id_grouped sum_up sum_down ... over_200_up 
1:   a1  1   0 ...   0 
2:   a2  0   1     0 
3:   a3  2   0 ...   1 
4:   a4  0   0     0 
5:   a5  0   0 ...   0 

Trước khi tôi đã làm nó với mã R (sử dụng data.table)

>DT[ ,list(A_id_grouped, sum_up = sum(B == "up"), 
+ sum_down = sum(B == "down"), 
+ ..., 
+ over_200_up = sum(up == "up" & < 200), by=list(A)]; 

Tuy nhiên tất cả các những nỗ lực gần đây của tôi với Python đã không thành công với tôi:

DT.agg({"D": [np.sum(DT[DT["B"]=="up"]),np.sum(DT[DT["B"]=="up"])], ... 
    "C": np.sum(DT[(DT["B"]=="up") & (DT["C"]>200)]) 
    }) 

Cảm ơn bạn trước! nó có vẻ như một câu hỏi đơn giản tuy nhiên tôi không thể tìm thấy nó ở bất cứ đâu.

Trả lời

14

Để bổ sung cho câu trả lời unutbu của, đây là một cách tiếp cận sử dụng apply trên đối tượng groupby.

>>> df.groupby('A_id').apply(lambda x: pd.Series(dict(
    sum_up=(x.B == 'up').sum(), 
    sum_down=(x.B == 'down').sum(), 
    over_200_up=((x.B == 'up') & (x.C > 200)).sum() 
))) 
     over_200_up sum_down sum_up 
A_id        
a1    0   0  1 
a2    0   1  0 
a3    1   0  2 
a4    0   0  0 
a5    0   0  0 
6

Có thể có cách tốt hơn; Tôi khá mới để gấu trúc, nhưng hoạt động này:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({'A_id':'a1 a2 a3 a3 a4 a5'.split(), 
        'B': 'up down up up left right'.split(), 
        'C': [100, 102, 100, 250, 100, 102]}) 

df['D'] = (df['B']=='up') & (df['C'] > 200) 
grouped = df.groupby(['A_id']) 

def sum_up(grp): 
    return np.sum(grp=='up') 
def sum_down(grp): 
    return np.sum(grp=='down') 
def over_200_up(grp): 
    return np.sum(grp) 

result = grouped.agg({'B': [sum_up, sum_down], 
         'D': [over_200_up]}) 
result.columns = [col[1] for col in result.columns] 
print(result) 

mang

 sum_up sum_down over_200_up 
A_id        
a1   1   0   0 
a2   0   1   0 
a3   2   0   1 
a4   0   0   0 
a5   0   0   0 
Các vấn đề liên quan