2016-02-14 3 views
0

Я пытаюсь np.vectorize аа один период видел функцию зуба с помощью numpy.vectorize с этой лямбда-функции:Numpy Vectorize Поведение

saw = lambda x: 0 if x < -2 or x > 2 else x 

Но когда я применяю векторизованную saw к этому массиву:

array([-4. , -3.57894737, -3.15789474, -2.73684211, -2.31578947, 
    -1.89473684, -1.47368421, -1.05263158, -0.63157895, -0.21052632, 
    0.21052632, 0.63157895, 1.05263158, 1.47368421, 1.89473684, 
    2.31578947, 2.73684211, 3.15789474, 3.57894737, 4.  ]) 

я получаю:

array([ 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 
    0, 0, 0]) 

Что здесь происходит?

Для рассмотрения я использую Python 2.7 с Numpy 1.10.2

+0

Просьба показать все соответствующие коды, которые вы использовали для его создания. Похоже, что ваши данные преобразуются в целые числа. Может быть, измените на 'saw = lambda x: 0.0 if x < -2 or x > 2 else x'? – SethMMorton

+0

Примечание: для этого лучше использовать 'np.where' вместо' np.vectorize'. 'np.vectorize' очень медленный. – user2357112

+0

В этом случае 'where' в 2 раза быстрее, чем' vectorize'. С булевым маскированием я могу сделать это 3 раза. – hpaulj

ответ

2

Согласно np.vectorize документации:

Тип выходного сигнала определяется путем оценки первого элемента входа, если он не является указанный

Ваш первый входной элемент производит выходной сигнал типа int64:

In [2]: data = np.array([-4. , -3.57894737, -3.15789474, -2.73684211, -2.31578947, 
    ...: -1.89473684, -1.47368421, -1.05263158, -0.63157895, -0.21052632, 
    ...:  0.21052632, 0.63157895, 1.05263158, 1.47368421, 1.89473684, 
    ...:  2.31578947, 2.73684211, 3.15789474, 3.57894737, 4.  ]) 

In [3]: saw = lambda x: 0 if x < -2 or x > 2 else x 

In [4]: saw_v = np.vectorize(saw) 

In [5]: type(saw_v(data)[0]) 
Out[5]: numpy.int64 

In [6]: type(saw_v(data[5:])[0]) 
Out[6]: numpy.float64 

Вы должны указать otype во время векторизации вашей функции:

In [9]: saw_v_f = np.vectorize(saw, otypes=[np.float]) 

In [10]: type(saw_v_f(data)[0]) 
Out[10]: numpy.float64 

In [11]: saw_v_f(data) 
Out[11]: 
array([ 0.  , 0.  , 0.  , 0.  , 0.  , 
     -1.89473684, -1.47368421, -1.05263158, -0.63157895, -0.21052632, 
     0.21052632, 0.63157895, 1.05263158, 1.47368421, 1.89473684, 
     0.  , 0.  , 0.  , 0.  , 0.  ]) 
+0

Просто изменил бы на 'saw = lambda x: 0.0 if x < -2 or x > 2 else x'работал? – SethMMorton

+0

@SethMMorton, да, это также делает трюк – soon

+0

RTF, как обычно, спасибо, @SethMMorton. –

-1

Кажется, работает для меня с картой.

map(saw, x) 

[0, 0, 0, 0, 0, -1.89473684, -1.47368421, -1.0526315799999999, -0.63157894999999997, -0.21052631999999999, 0.21052631999999999, 0.63157894999999997, 1.0526315799999999, 1.47368421, 1.89473684, 0, 0, 0, 0, 0] 
+0

... но ОП использует numpy. Это не имеет значения. – SethMMorton

+1

'np.array (list (map (saw, x)))' так же быстро, как 'vectorize' с этим массивом образцов. Итак, 'np.array ([saw (i) для i в x])' – hpaulj

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