2013-02-20 3 views
5

я попытался векторизации (согласованный, не самый эффективный способ сделать это, но мой вопрос скорее об использовании декоратор) следующая функцияNumpy векторизовать как декоратор с аргументами

@np.vectorize 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 

x = np.array([5.6, 7.0]) 
y = 8 

diff_if_bigger(x, y) 
# outputs array([2, 1]) which is not what I want 

EDIT: После перезапуска IPython выход был в порядке.

Может кто-нибудь объяснить, почему результат diff_if_bigger получил tansformed в массив np.int, даже если первый аргумент х в данном случае является Арай из np.float, Вопреки тому, что в документе ????

Теперь я хочу, чтобы заставить выход поплавка, так что я сделал это

@np.vectorize('np.float') 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 
# Error !! 
# TypeError: Object is not callable. 

@np.vectorize(otypes='np.float') 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 
# Again error !! 
# TypeError: __init__() takes at least 2 arguments (2 given) 


@np.vectorize(otypes=[np.float]) 
def diff_if_bigger(x, y): 
    return y - x if y > x else 0 
# Still an error !! 
# TypeError: __init__() takes at least 2 arguments (2 given) 

Кстати, даже этот

vec_diff = np.vectorize(diff_if_bigger, otypes=[np.float]) 

не работает !!! Так, что происходит??

EDIT: Фактически последний работал после перезапуска IPython.

Таким образом, после моих предыдущих двух правок, мой вопрос теперь в два раза:

1- Как я могу использовать np.vectorize как декоратор с аргументами?

2- Как я могу очистить состояние IPython?

+0

@seberg, нет, вы говорите глупости. –

+0

Посмотрите, вы действительно не отвечаете конкретно ни на один из моих вопросов. Вы даже пытались запустить код, который я разместил? Вы посмотрели на помощь векторизации? –

+0

Извините, но, возможно, вам следует дать более подробные описания ошибок, это немного сложно диагностировать. 1. На самом деле все ваши примеры работают (но у декораторов есть тип, который не может). 2. Ваш первый пример может потерпеть неудачу, если вы представили другой ввод перед этим вводом. 3. Последний вызов векторизации на функцию, которая уже векторизована, не имеет смысла, так что, возможно, это ваша зловещая «не работает». – seberg

ответ

7

работает для меня:

>>> import numpy as np 
>>> @np.vectorize 
... def diff_if_bigger(x, y): 
...  return y - x if y > x else 0 
... 
>>> diff_if_bigger(np.array([5.6,7.0]), 8) 
array([ 2.4, 1. ]) 

Обратите внимание, что np.vectorize на самом деле не предназначены в качестве декоратора для простейших случаев. Если вам нужно указать явное otype, используйте обычную форму new_func = np.vectorize(old_func, otypes=...) или используйте functools.partial, чтобы получить декоратор.

Примечание также, что np.vectorize, по умолчанию, получает свой тип вывода из оценки функции от первого аргумента:

Тип данных на выходе vectorized определяется путем вызова функции с первым элементом вход.

Таким образом, вы должны пройти float и вернуть float, если вы хотите, чтобы убедиться, что он выводит float в качестве выходного DTYPE (например, использовать else 0.0 и передать y = 8.0).

+0

Моя версия numpy 1.6.1 .. и я не получаю то же поведение, что и вы, но тот, который я упомянул в своем сообщении. В моем случае первый вход x является массивом 'np.float', поэтому почему я получаю массив' np.int' в конце? Но хуже, как я упоминал в своем OP, у меня появились ошибки, даже если я не использовал np.vectorize в качестве декоратора !! –

+1

это не первый «ввод», который имеет значение, но первый «вывод» и «0» не является поплавком. – seberg

+0

@nneonneo Я боюсь, что поведение, которое я получил, связано с внутренним состоянием моего сеанса IPython. Но тогда я не могу понять, почему этот сеанс был поврежден до такой степени, что np.vectorize не вел себя так, как объявлено в документах. –

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