Я написал функцию, она кажется вам подходит.
def amap(func, *args):
'''array version of build-in map
amap(function, sequence[, sequence, ...]) -> array
Examples
--------
>>> amap(lambda x: x**2, 1)
array(1)
>>> amap(lambda x: x**2, [1, 2])
array([1, 4])
>>> amap(lambda x,y: y**2 + x**2, 1, [1, 2])
array([2, 5])
>>> amap(lambda x: (x, x), 1)
array([1, 1])
>>> amap(lambda x,y: [x**2, y**2], [1,2], [3,4])
array([[1, 9], [4, 16]])
'''
args = np.broadcast(None, *args)
res = np.array([func(*arg[1:]) for arg in args])
shape = args.shape + res.shape[1:]
return res.reshape(shape)
Позвольте попробовать
def f(x):
return x * np.array([1,1,1,1,1], dtype=np.float32)
amap(f, np.arange(4))
Выходы
array([[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3.]], dtype=float32)
Вы также можетеОберните его лямбда или частичное для удобства
g = lambda x:amap(f, x)
g(np.arange(4))
Обратите внимание, что строка документа vectorize
говорит:
Функция vectorize
предназначена в основном для удобства, а не дляспектакль.Реализация по сути является циклом for.
Таким образом, мы ожидаем, что amap
здесь будет иметь производительность, аналогичную vectorize
.Я не проверял, приветствуются любые тесты производительности.
Если производительность действительно важна, вы должны рассмотреть что-то другое, например, прямой расчет массива с reshape
и broadcast
, чтобы избежать цикла в чистом Python(оба vectorize
и amap
являются последним регистром).