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?
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).
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.
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.
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.
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
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With