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
Другие вопросы по тегам