numpy.vectorize takes a function f:a->b and turns it into g:a[]->b[].

This works fine when a and b are scalars, but I can't think of a reason why it wouldn't work with b as an ndarray or list.

For example:

import numpy as np
def f(x): return np.array([1,1,1,1,1], dtype=np.float32) * x
g = np.vectorize(f, otypes=[np.ndarray])
a = np.arange(4)

print(a)
array([[ 0.  0.  0.  0.  0.], [ 1.  1.  1.  1.  1.], [ 2.  2.  2.  2.  2.],
       [ 3.  3.  3.  3.  3.]], dtype=object)

gives the right answer values, but the wrong dtype. And even worse:

x.shape
(4,)

So this array is pretty much useless. I know I can convert it like this:

np.array(map(list, a), dtype=np.float32)

to give me what I want,

array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.]], dtype=float32)

but that is neither efficient nor pythonic. Can any of you guys find a cleaner way to do this?

Thanks in advance!

Edited 6 Years Ago by prodigenius: n/a

import numpy as np

def f(x): return np.array([1,1,1,1,1], dtype=np.float32) * x

g = np.vectorize(f, otypes=[np.ndarray])
a = np.arange(4)

print(a)
print repr(g(a))

Edited 6 Years Ago by pyTony: n/a

No, it is not solved. Your solution has the exact same problem is my line 7 - it gives a numpy object array, not a numpy float array. Did you test it?

repr(g(a)) == 'array([[ 0. 0. 0. 0. 0.], [ 1. 1. 1. 1. 1.], [ 2. 2. 2. 2. 2.],[ 3. 3. 3. 3. 3.]], dtype=object)'

Why not without vectorize, then?

import numpy as np
def f(x): return np.array([1.0,1.0,1.0,1.0,1.0], dtype=np.float32) * x
g = np.vectorize(f, otypes=[np.ndarray])
a = np.arange(4)
a = np.array(a, dtype=np.float32)

print(a)

res = np.array(map(list, g(a)), dtype=np.float32) ## g(a) not a
print repr(res)
print res.shape

# Why not without vectorize?
res2 =np.array([5*[elem] for elem in a])
print repr(res2)
print res.shape
""" Output:
[ 0.  1.  2.  3.]
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.]], dtype=float32)
(4, 5)
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.]], dtype=float32)
(4, 5)
"""

Edited 6 Years Ago by pyTony: n/a

One bug in the program: Line 16 should have res2.shape, not res.shape. However the result is really the same (4, 5)

So shortly my suggestion was:

import numpy as np
res =np.array([5*[elem] for elem in np.arange(4.0)], dtype=np.float32)
print repr(res)
print res.shape
""" Output:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.]], dtype=float32)
(4, 5)
"""
This question has already been answered. Start a new discussion instead.