2012-04-04 34 views
6

Có thể trực tiếp tính toán sản phẩm (hoặc ví dụ tổng hợp) của hai cột mà không sử dụngchức năng groupby bằng Python Pandas như SUM (col_1 * col_2), bình quân gia quyền vv

grouped.apply(lambda x: (x.a*x.b).sum() 

Đó là nhiều (ít hơn một nửa thời gian trên máy của tôi) nhanh hơn để sử dụng

df['helper'] = df.a*df.b 
grouped= df.groupby(something) 
grouped['helper'].sum() 
df.drop('helper', axis=1) 

Nhưng tôi thực sự không thích phải làm điều này. Ví dụ: Ví dụ: hữu ích để tính toán mức trung bình có trọng số cho mỗi nhóm. Ở đây, cách tiếp cận lambda sẽ là

grouped.apply(lambda x: (x.a*x.b).sum()/(df.b).sum()) 

và lại chậm hơn nhiều so với việc chia helper cho b.sum().

Trả lời

7

Tôi muốn cuối cùng xây dựng một đánh giá biểu thức mảng nhúng (Numexpr trên steroid) để làm những việc như thế này. Ngay bây giờ chúng tôi đang làm việc với những hạn chế của Python-- nếu bạn thực hiện một aggregator Cython làm (x * y).sum() sau đó nó có thể được kết nối với groupby, nhưng lý tưởng bạn có thể viết biểu thức Python là một hàm:

def weight_sum(x, y): 
    return (x * y).sum() 

và mà sẽ nhận được "JIT biên dịch" và được về nhanh như groupby (...). sum(). Những gì tôi mô tả là một dự án khá đáng kể (nhiều tháng). Nếu có một triển khai APL tương thích với BSD, tôi có thể thực hiện một số việc như trên sớm hơn một chút (chỉ cần suy nghĩ to).

0

Làm thế nào về trực tiếp nhóm kết quả của x.a * x.b, ví dụ:

from pandas import * 
from numpy.random import randn 
df = DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 
       'foo', 'bar', 'foo', 'foo'], 
     'B' : ['one', 'one', 'two', 'three', 
       'two', 'two', 'one', 'three'], 
     'C' : randn(8), 'D' : randn(8)}) 

print (df.C*df.D).groupby(df.A).sum() 
+0

này hoạt động của khóa học. Nhưng tôi nghi ngờ rằng đầu tiên toàn bộ vector C * D được xây dựng trong bộ nhớ, sau đó nó được nhóm lại và sau đó tổng kết. Tôi sẽ không phải làm điều này nếu tôi có thể đi qua các hàng một cách hiệu quả, cộng lại c_i * d_i (hoặc chỉ xây dựng nhóm C * D và sau đó tổng hợp chúng trong khi đi qua các nhóm). –

0

Câu trả lời đến nhiều năm sau qua pydata blaze

from blaze import * 
data = Data(df) 
somethings = odo(
by(data.something, 
    wm = (data.a * data.weights).sum()/data.weights.sum()), 
pd.DataFrame) 
Các vấn đề liên quan