Как исправить проблемы с трансляцией с помощью numpy.vectorize () - PullRequest
0 голосов
/ 04 февраля 2019

Я пишу пользовательскую функцию, которая должна работать так, как если бы она была 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])

Как правильно использовать эту функцию?

1 Ответ

0 голосов
/ 04 февраля 2019

Вы указали excluded неправильно.

In [270]: def foo(x, param):
     ...:     a,b,c = param
     ...:     return a*x
     ...: 
In [271]: f = np.vectorize(foo, excluded=[1])  # specify by position
In [272]: f(np.arange(4),[1,3,2])
Out[272]: array([0, 1, 2, 3])

Для ключевого слова arg:

In [277]: def foo(x, param=[0,0,0]):
     ...:     a,b,c = param
     ...:     return a*x
     ...:
In [278]: f = np.vectorize(foo, excluded=['param'])
In [279]: f(np.arange(4),param=[1,3,2])
Out[279]: array([0, 1, 2, 3])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...