Я пишу пользовательскую функцию, которая должна работать так, как если бы она была numpy-функцией, иметь возможность принимать массив и выполнять ту же операцию для каждого элемента входного списка и возвращать списокодинаковой формы со всеми результатами.
К счастью, есть решение для этого: numpy.vectorize()
Так что я использовал это: У меня есть функция, которая создаетмодель в форме синусоиды, и она принимает две переменные: один список NumPy X
, содержащий некоторые входные значения для функции синуса, и один список NUMPY param
, который содержит четыре возможных параметра, которые может иметь синусоида,
import numpy as np
def sine(X, param):
#Unpacking param
A = param[0]
P = param[1]
Phi = param[2]
B = param[3]
#translating variables
#Phi = t0/P
f = X/P
Y = A*np.sin(2*np.pi*(f + Phi)) + B
return Y
Поскольку только входные значения X
нуждаются в широковещании, в то время как все параметры необходимы постоянно, поэтому, согласно документации, способ проверки функции заключается в следующем:
np_sine = np.vectorize(sine, excluded=['param']) #makes sine() behave like a numpy function
... так что param
должным образом исключен из векторизации.
Этот метод полезен, так как я буду приспосабливать эту модель к набору данных, который иногда требует настройки параметров,Между тем, с помощью этого метода код, в котором я нуждаюсь, имеет длину только одну строку:
CHIsqrt = np.sum(((ydata - np_sine(xdata, param))/yerr)**2)
, где ydata
, xdata
и yerr
- одинаково длинные списки точек данных и где param
- этосписок из четырех параметров.
Тем не менее, результатом была ошибка широковещания:
File "C:\Users\Anonymous\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\lib\function_base.py", line 2831, in _vectorize_call outputs = ufunc(*inputs)
ValueError: operands could not be broadcast together with shapes (500,) (4,)
Поскольку список param
имеет длину 4 элемента, я получаю, что функция игнорировала мои командыисключить его из векторизации.Это проблема.
Я попытался указать, что конечным результатом должен быть ndArray, который не изменил ошибку.
np_sine = np.vectorize(sine, excluded=['param'], otypes=[np.ndarray])
Как правильно использовать эту функцию?