2014-11-03 21 views
10

Tôi có khung dữ liệu gấu trúc bao gồm các nhóm con khác nhau.Cách nhanh hơn để xếp hạng các hàng trong các nhóm con trong khung dữ liệu gấu trúc

df = pd.DataFrame({ 
    'id':[1, 2, 3, 4, 5, 6, 7, 8], 
    'group':['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'], 
    'value':[.01, .4, .2, .3, .11, .21, .4, .01] 
    }) 

Tôi muốn tìm thứ hạng của từng id trong nhóm của nó với giá trị thấp hơn sẽ tốt hơn. Trong ví dụ trên, trong nhóm A, Id 1 sẽ có xếp hạng 1, Id 2 sẽ có xếp hạng 4. Trong nhóm B, Id 5 sẽ có xếp hạng là 2, Id 8 sẽ có xếp hạng là 1 và trên.

Ngay bây giờ tôi đánh giá cấp bậc theo:

  1. Phân loại theo giá trị.

    df.sort('value', ascending = True, inplace=True)

  2. Tạo một hàm lính trơn (nó giả định các biến đã được sắp xếp)

    def ranker(df): df['rank'] = np.arange(len(df)) + 1 return df

  3. Áp dụng các chức năng lính trơn đối với từng nhóm riêng biệt:

    df = df.groupby(['group']).apply(ranker)

Quá trình này hoạt động nhưng nó thực sự chậm khi tôi chạy nó trên hàng triệu hàng dữ liệu. Có ai có bất kỳ ý tưởng về cách làm cho một chức năng ranker nhanh hơn.

Trả lời

19

xếp hạng được mã hóa nên sẽ rất nhanh. Và bạn có thể chuyển các tùy chọn tương tự như df.rank() here là tài liệu cho rank. Như bạn có thể thấy, việc ngắt kết nối có thể được thực hiện theo một trong năm cách khác nhau thông qua đối số method.

Cũng có thể bạn chỉ muốn .cumcount() của nhóm.

In [12]: df.groupby('group')['value'].rank(ascending=False) 
Out[12]: 
0 4 
1 1 
2 3 
3 2 
4 3 
5 2 
6 1 
7 4 
dtype: float64 
+0

tất nhiên! có một chức năng cho nó! Điều đó nói rằng, nó không hoàn toàn làm điều tương tự như chức năng của tôi ở trên bởi vì nếu có một tie trong các giá trị, chức năng của tôi sẽ ngẫu nhiên cho một id một thứ hạng cao hơn một id với cùng một giá trị. Mặc dù .rank() 's cách xử lý các giá trị tương tự là khá hợp lý, cho mục đích của tôi, tôi cần đầu ra được sản xuất bởi chức năng của tôi. Cảm ơn bạn đã giúp đỡ! –

+0

Tôi đã cập nhật một phương án thay thế. – Jeff

9

Làm việc với một DataFrame lớn (13 triệu dòng), xếp hạng phương pháp với nhóm tối đa 8GB RAM của tôi mất một thời gian rất dài. Tôi tìm thấy một cách giải quyết ít tham lam hơn trong trí nhớ, rằng tôi đặt ở đây chỉ trong trường hợp:

df.sort_values('value') 
tmp = df.groupby('group').size() 
rank = tmp.map(range) 
rank =[item for sublist in rank for item in sublist] 
df['rank'] = rank 
Các vấn đề liên quan