2013-08-16 21 views
12

Ở nhiều nơi trong mã sử dụng Pandas của chúng tôi, chúng tôi có một số chức năng Python process(row). Hàm đó được sử dụng trên DataFrame.iterrows(), lấy mỗi row và thực hiện một số quá trình xử lý và trả về một giá trị mà chúng tôi thu thập tối đa vào một Series mới.Xử lý hiệu quả các hàng DataFrame bằng hàm Python?

Tôi nhận thấy mẫu sử dụng này phá vỡ hầu hết các lợi ích hiệu suất của ngăn xếp khối/chồng.

  1. Cách tốt nhất để làm cho mẫu sử dụng này hiệu quả như thế nào càng tốt?
  2. Chúng tôi có thể làm điều đó mà không cần viết lại hầu hết mã của chúng tôi không?

Một khía cạnh khác của câu hỏi này: tất cả các chức năng như vậy có thể được chuyển đổi thành đại diện gọn gàng không? Tôi đã tìm hiểu nhiều về ngăn xếp lộn xộn/scipy/Pandas, nhưng có vẻ như đối với logic thực sự tùy ý, đôi khi bạn có thể chỉ cần sử dụng một kiến ​​trúc Python chậm tinh khiết giống như ở trên. Đó là trường hợp?

+0

Nếu bạn đang làm toán, bạn sẽ có thể thực hiện các hoạt động được vector hóa. Nếu bạn đang sử dụng chuỗi hoặc các kiểu dữ liệu không cố định khác, bạn có thể thực hiện phép toán theo các con số theo cách vecorized, sau đó làm hàng dựa trên phần còn lại ... bạn có thể cung cấp một số chi tiết về những gì bạn đang làm không? –

Trả lời

19

Bạn nên áp dụng hàm của mình dọc theo trục = 1. Chức năng sẽ nhận được hàng như một cuộc tranh cãi, và bất cứ điều gì nó sẽ trả về sẽ được thu thập vào một đối tượng loạt mới

df.apply(you_function, axis=1) 

Ví dụ:

>>> df = pd.DataFrame({'a': np.arange(3), 
         'b': np.random.rand(3)}) 
>>> df 
    a   b 
0 0 0.880075 
1 1 0.143038 
2 2 0.795188 
>>> def func(row): 
     return row['a'] + row['b'] 
>>> df.apply(func, axis=1) 
0 0.880075 
1 1.143038 
2 2.795188 
dtype: float64 

Đối với phần thứ hai của câu hỏi: hoạt động khôn ngoan hàng, thậm chí những người được tối ưu hóa, sử dụng gấu trúc apply, không phải là giải pháp nhanh nhất có. Chúng chắc chắn là nhiều hơn nhanh hơn một con trăn cho vòng lặp, nhưng không phải là nhanh nhất. Bạn có thể kiểm tra điều đó bằng cách tính toán thời gian và bạn sẽ thấy sự khác biệt.

Một số hoạt động có thể được chuyển đổi thành các cột được định hướng (một trong ví dụ của tôi có thể dễ dàng chuyển đổi thành chỉ df['a'] + df['b']), nhưng một số khác thì không. Đặc biệt là nếu bạn có nhiều nhánh, trường hợp đặc biệt hoặc logic khác nên được thực hiện trên hàng của bạn. Trong trường hợp đó, nếu apply quá chậm đối với bạn, tôi sẽ đề xuất "Cython-izing" mã của bạn. Cython chơi thực sự độc đáo với các api NumPy C và sẽ cung cấp cho bạn tốc độ tối đa bạn có thể đạt được.

Hoặc bạn có thể thử numba. :)

+0

Lỗi đánh máy nhỏ trong 'applay' :) –

+0

@PhillipCloud Tôi thấy rằng bạn hiếm khi sử dụng áp dụng dọc theo' trục = 1'. Có lý do hiệu suất cụ thể nào không? Không phải đó là cách nhanh nhất để lật đổ hàng mảng một cách khôn ngoan? –

+0

Tôi tin là vậy. Không có lý do cụ thể, tôi chỉ thường làm việc với dữ liệu được định hướng cột vì vậy tôi không phải sử dụng nó (vì vậy nó không thực sự ở đầu tâm trí của tôi). Tôi cũng có một nghi ngờ rằng các hoạt động dọc theo các hàng có thể tránh được hầu hết thời gian bởi một số hoạt động định hình lại hoặc nhóm ', nhưng tôi không có bằng chứng nào để sao lưu, chỉ trực giác của tôi có thể sai ở đây. –