Numpy vectorize as a decorator with arguments
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
).
Related videos on Youtube
Comments
-
green diod about 2 years
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 ofnp.int
even if the first argument x is here an aray ofnp.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?
-
green diod over 11 years@seberg, your comment about me not doing enough great research was offensive even if you deleted it. If I ask questions here on SO, it's after trying things, reading the docs, going through the manuals and so on. I wouldn't even distrurb you with my dumb questions anyway if I was able to do the kind of great research you're referring to. In your first comment that you also deleted, you talked about the difference about np.float and np.float_ but I didn't see how it could relate to my problem. Now you also downvoted me, I don't care.
-
-
green diod over 11 yearsMy numpy version is 1.6.1 .. and I don't get the same behavior as you report but the one I mentioned in my post. In my cas, the first input x is an array of
np.float
's so why do I get an array ofnp.int
at the end?? But worse, as I mentioned in my OP, I got errors even if I didn't use np.vectorize as a decorator!! -
seberg over 11 yearsit is no the first "input" that matters, but the first "output" and 0 is not a float.
-
green diod over 11 years@nneonneo I'm afraid that the behavior I got was because of the internal state of my IPython session. But then, I can't figure out why that session got corrupted to the point where the np.vectorize didn't behave like announced in the docs.
-
green diod over 11 years@seberg the doc says that the output depends on the type of the first input ...