2014-10-08 15 views
5

Cách hiệu quả (tốc độ) để áp dụng các chức năng Piecewise trên Numpy Array là gì?Chức năng Piecewise trên Numpy Arrays

Say, ví dụ, chức năng piecewise giống như

For (1) : x<=2 f(x) = 2*x + x^2 
    (2) : x>2 f(x) = -(x^2 + 2) 

Đây là những gì tôi đã làm.

data = np.random.random_integers(5, size=(5,6)) 
print data 
np.piecewise(data, [data <= 2, data > 2], 
      [lambda x: 2*x + pow(2, x), 
       lambda x: -(pow(x, 2) + 2)]) 

data = 
[[4 2 1 1 5 3] 
[4 3 3 5 4 5] 
[3 2 4 2 5 3] 
[2 5 4 3 1 4] 
[5 3 3 5 5 5]] 
output = 
array([[-18, 8, 4, 4, -27, -11], 
     [-18, -11, -11, -27, -18, -27], 
     [-11, 8, -18, 8, -27, -11], 
     [ 8, -27, -18, -11, 4, -18], 
     [-27, -11, -11, -27, -27, -27]]) 

Có phương pháp hiệu quả để đi theo mảng nhỏ hơn, mảng lớn, nhiều chức năng, v.v ... không? Mối quan tâm của tôi là với các hàm lambda đang được sử dụng. Không chắc chắn nếu chúng được tối ưu hóa Numpy.

Trả lời

3

Trong trường hợp này, bạn không nên quan tâm đến lambdas: Tối ưu hóa tối ưu là giảm chi phí cuộc gọi, bằng cách cho phép chức năng đánh giá nhiều giá trị cùng một lúc trong hàng loạt. Trong mỗi cuộc gọi đến np.piecewise, mỗi chức năng trong funclist (các phần chức năng) được gọi chính xác một lần, với một mảng bao gồm tất cả các giá trị trong đó điều kiện thích hợp là đúng. Do đó, những lambda này được gọi theo cách tối ưu.

Tương tự là np.select (và np.where cho chính xác hai phần). Chi phí cuộc gọi là giống như nó được vector hóa theo cùng một cách, nhưng nó sẽ đánh giá tất cả các chức năng cho tất cả các điểm dữ liệu. Do đó, nó sẽ chậm hơn np.piecewise, đặc biệt là khi các chức năng đắt tiền. Trong một số trường hợp, là thuận tiện hơn (không có lambda), và người ta có thể dễ dàng mở rộng khái niệm này sang nhiều biến.

+0

Câu trả lời hay. Một lợi thế khác của việc sử dụng 'np.select()' hoặc 'np.where()' là sau đó bạn có quyền truy cập vào toàn bộ mảng khi thực hiện các phép tính. Nếu hàm của bạn phụ thuộc vào các giá trị khác trong đầu vào (ví dụ, các giá trị lân cận của mỗi điểm), điều này sẽ hữu ích. Nhưng trong trường hợp của OP nó không quan trọng, và 'np.piecewise()' là tốt. –

Các vấn đề liên quan