Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy vectorize as a decorator with arguments

I tried to vectorize (agreed, not the most efficient way to do it, but my question is rather on the decorator use) the following function

 @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: After restarting IPython, the output was OK.

Can anyone explain why the result of diff_if_bigger got tansformed into an array of np.int even if the first argument x is here an aray of np.float, contrarily to what's in the doc????

Now, I want to force a float output, so I did this

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

By the way, even this

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

doesn't work!!! So what's going on??

EDIT: In fact, the latter worked after I restarted IPython.

So after my previous two edits, my question is now twofold:

1- How can I use np.vectorize as a decorator with arguments?

2- How can I clean IPython state?

like image 727
green diod Avatar asked Feb 20 '13 17:02

green diod


People also ask

Is NumPy vectorize faster than for loop?

Vectorized implementations (numpy) are much faster and more efficient as compared to for-loops. To really see HOW large the difference is, let's try some simple operations used in most machine learnign algorithms (especially deep learning).

What does vectorize do in NumPy?

The vectorized function evaluates pyfunc over successive tuples of the input arrays like the python map function, except it uses the broadcasting rules of numpy. The data type of the output of vectorized is determined by calling the function with the first element of the input.

Why is NumPy vectorize fast?

A major reason why vectorization is faster than its for loop counterpart is due to the underlying implementation of Numpy operations. As many of you know (if you're familiar with Python), Python is a dynamically typed language.

What is Guvectorize?

The @guvectorize decorator While vectorize() allows you to write ufuncs that work on one element at a time, the guvectorize() decorator takes the concept one step further and allows you to write ufuncs that will work on an arbitrary number of elements of input arrays, and take and return arrays of differing dimensions.


1 Answers

Works for me:

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

Note that np.vectorize isn't really meant as a decorator except for the simplest cases. If you need to specify an explicit otype, use the usual form new_func = np.vectorize(old_func, otypes=...) or use functools.partial to get a decorator.

Note too that np.vectorize, by default, gets its output type from evaluating the function on the first argument:

The data type of the output of vectorized is determined by calling the function with the first element of the input.

So, you should pass float and return float if you want to ensure that it infers float as the output dtype (e.g. use else 0.0 and pass y = 8.0).

like image 151
nneonneo Avatar answered Oct 21 '22 21:10

nneonneo