2014-10-08 3 views
5

Что такое эффективный способ (скорость) применения кусочных функций на массиве Numpy?Кусочные функции на массивах Numpy

Скажем, к примеру, функции Кусочно подобны

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

Вот что я сделал.

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]]) 

Есть ли эффективный метод для небольших массивов, больших массивов, множества функций и т. Д.? Меня беспокоит использование лямбда-функций. Не уверены, оптимизированы ли они.

ответ

3

В этом случае вы не должны беспокоиться о лямбдах: оптимизация Numpy заключается в сокращении накладных расходов на вызов, позволяя функциям одновременно оценивать множество значений в пакете. В каждом вызове np.piecewise каждая функция в funclist (функциональные части) вызывается ровно один раз, с массивом numpy, состоящим из всех значений, где соответствующее условие истинно. Таким образом, эти лямбды вызываются оптимизированным образом.

Аналогичные np.selectnp.where для ровно двух частей). Накладные расходы на вызов такие же, как и векторизованные, но они будут оценивать все функции для всех точек данных. Таким образом, он будет медленнее, чем np.piecewise, особенно когда функции дороги. В некоторых случаях это более удобно (без лямбда), и более легко расширить понятие до многих переменных.

+0

Хороший ответ. Еще одно преимущество использования 'np.select()' или 'np.where()' заключается в том, что тогда вы получаете доступ ко всему массиву при выполнении вычислений. Если ваша функция зависит от других значений ввода (например, соседних значений каждой точки), это будет полезно. Но в случае OP это не имеет значения, а 'np.piecewise()' хорошо. –

Смежные вопросы