I have a numpy.ndarray x
of shape (...,3)
i.e. with an arbitrary number of axes, the last axis having a known size of 3.
I also have a function f
that takes as argument an array of shape (3)
(in fact a point in a 3D space) and returns another array of shape (3)
(in fact a vector in a 3D space). Unfortunately, this function cannot (at least easily) be vectorized.
Using numpy.nditer
, how can I efficiently parse the array x
along all its axes except the last one in order to fill an array y
(whose shape is equal to the one of x
) with the result of f
?
The following piece of code will do it without use of nditer :
import numpy as np
def f(x):
'''Simple function for this exemple.
Can only deal with array of shape (3,)
'''
assert x.ndim == 1 and x.shape[0] == 3
y = np.zeros_like(x)
y[0] = x[0]
y[1] = x[1]**2
y[2] = x[2]**3
return y
x = np.arange(15).reshape(5,3)
_x = x.reshape(-1,3)
_y = np.zeros_like(_x)
for i in xrange(_x.shape[0]):
_y[i,:] = f(_x[i,:])
y = _y.reshape(x.shape)
but does not look 'pythonic' to me.
As a bonus question, will there be an advantage in terms of speed in using nditer rather than the classical python loop above ?