make np.vectorize возвращает скалярное значение на скалярном входе
Следующий код возвращает массив вместо ожидаемого значения с плавающей запятой.
def f(x):
return x+1
f = np.vectorize(f, otypes=[np.float])
>>> f(10.5)
array(11.5)
Есть ли способ заставить его вернуть простое скалярное значение, если вход является скалярным, а не странным типом массива?
Я нахожу это странным, он не делает это по умолчанию, учитывая, что все другие функции, такие как np.cos, np.sin и т. Д., Возвращают обычные скаляры
Редактировать: это код, который работает:
import numpy as np
import functools
def as_scalar_if_possible(func):
@functools.wraps(func) #this is here just to preserve signature
def wrapper(*args, **kwargs):
return func(*args, **kwargs)[()]
return wrapper
@as_scalar_if_possible
@np.vectorize
def f(x):
return x + 1
print (f (11.5)) # печатает 12.5
1 ответ
Результатом является технически скаляр, так как его форма ()
, Например, np.array(11.5)[0]
не является допустимой операцией и приведет к исключению. Действительно, возвращаемые результаты будут действовать как скаляр в большинстве случаев.
например.
x = np.array(11.5)
print(x + 1) # prints 12.5
print(x < 12) # prints True, rather than [ True]
x[0] # raises IndexError
Если вы хотите получить "правильное" скалярное значение обратно, вы можете просто обернуть векторизованную функцию, чтобы проверить форму возвращаемого массива. Это то, что тупые уфунки делают за кулисами.
например.
import numpy as np
def as_scalar_if_possible(func):
def wrapper(arr):
arr = func(arr)
return arr if arr.shape else np.asscalar(arr)
return wrapper
@as_scalar_if_possible
@np.vectorize
def f(x):
return x + 1
print(f(11.5)) # prints 12.5