Общий размер массива должен быть неизменным

Я использую модуль Python emcee для демонстрации дистрибутива. Мне нужно передать (37,100) (который я назвал Ntrig и Nsamp, соответственно) массив под названием events к функции ниже.

def mp(SNR2, *events):
    events = np.asarray(events).reshape((Ntrig,Nsamp))
    bessel = special.iv(0,np.sqrt(x*SNR2(event)))
    exp = np.exp(-0.5*(x+SNR2(event)))
    I = integrate.quad(lambda x: exp*bessel,0,SNRth**2)[0]
    return np.asarray([np.array[I for event in events[i]] for i in range(len(events))]).reshape(events.shape)

Я продолжаю получать ошибку:

ValueError: total size of new array must be unchanged

Насколько я понимаю, *events сломать events массив в 37*100 отдельных аргументов. Разве следующая строка, где я изменяю массив, не должна просто поместить его обратно в массив 37 на 100?

PS прежде чем спросить почему я вообще заморачиваюсь events на отдельные аргументы - модуль должен работать, он не может принимать массив.

Ошибка полной трассировки:

ValueError                                Traceback (most recent call last)
<ipython-input-17-c8e815326a69> in <module>()
----> 1 mp(SNR2,events)

<ipython-input-16-9f73f234c628> in mp(SNR2, *events)
      5 def mp(SNR2, *events):
      6     events = np.asarray(events).reshape((Ntrig,Nsamp))
----> 7     return np.asarray([np.array([integrate.quad(lambda x: np.exp(-0.5*(x+SNR2(event)))*special.iv(0,np.sqrt(x*SNR2(event))),0,SNRth**2)[0] for event in events[i]]) for i in range(len(events))]).reshape(events.shape)
      8 #    return integrate.quad(lambda x: 0.5*np.exp(-0.5*(x+SNR2(event)))*special.iv(0,np.sqrt(x*SNR2(event))),0,SNRth**2)[0]
      9 def pp(SNR2, *events):

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in quad(func, a, b, args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst)
    279         args = (args,)
    280     if (weight is None):
--> 281         retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
    282     else:
    283         retval = _quad_weight(func,a,b,args,full_output,epsabs,epsrel,limlst,limit,maxp1,weight,wvar,wopts)

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/integrate/quadpack.pyc in _quad(func, a, b, args, full_output, epsabs, epsrel, limit, points)
    343     if points is None:
    344         if infbounds == 0:
--> 345             return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
    346         else:
    347             return _quadpack._qagie(func,bound,infbounds,args,full_output,epsabs,epsrel,limit)

<ipython-input-16-9f73f234c628> in <lambda>(x)
      5 def mp(SNR2, *events):
      6     events = np.asarray(events).reshape((Ntrig,Nsamp))
----> 7     return np.asarray([np.array([integrate.quad(lambda x: np.exp(-0.5*(x+SNR2(event)))*special.iv(0,np.sqrt(x*SNR2(event))),0,SNRth**2)[0] for event in events[i]]) for i in range(len(events))]).reshape(events.shape)
      8 #    return integrate.quad(lambda x: 0.5*np.exp(-0.5*(x+SNR2(event)))*special.iv(0,np.sqrt(x*SNR2(event))),0,SNRth**2)[0]
      9 def pp(SNR2, *events):

<ipython-input-16-9f73f234c628> in SNR2(*events)
      1 def SNR2(*events):
----> 2     events = np.asarray(events).reshape((Ntrig,Nsamp))
      3     C = 5*np.pi**(-1.33333)*events**(1.66667)/(96*d**2)
      4     return C*integrate.quad(lambda f: f**(-2.3333)/S(f), 20, 1500, limit=1000)[0]
      5 def mp(SNR2, *events):

ValueError: total size of new array must be unchanged

1 ответ

Решение

Насколько я понимаю, events разбит массив событий на 37*100 отдельных аргументов.

Это неправда. Если вы позвоните mp с помощью

mp(SNR2, events)

затем внутри mp, events будет кортеж из 1 элемента, (arr,), где arr является (37, 100)-образным массивом.

Если вы позвоните mp с помощью

mp(SNR2, *events)

затем внутри mp, events будет кортеж из 37 элементов, где 37 элементов - это 37 строк массива в форме (37, 100).

Если вы позвоните mp с помощью

mp(SNR2, *events.flat)

затем внутри mp, events будет кортеж из 37*100 элементов.


Обратите внимание, что последний раздел трассировки говорит:

<ipython-input-16-9f73f234c628> in SNR2(*events)
      1 def SNR2(*events):
----> 2     events = np.asarray(events).reshape((Ntrig,Nsamp))
      3     C = 5*np.pi**(-1.33333)*events**(1.66667)/(96*d**2)
      4     return C*integrate.quad(lambda f: f**(-2.3333)/S(f), 20, 1500, limit=1000)[0]
      5 def mp(SNR2, *events):

ValueError: total size of new array must be unchanged

Таким образом, ошибка возникает, когда Python находится в SNR2 функция.

поскольку SNR2 был вызван в mp с помощью SNR2(event), а также event является (37,100) -образный массив, event переменная в SNR2 является 1-элементным кортежем, содержащим исходный массив Это не то, что вы хотите.

Самый простой способ исправить код - это определить

def SNR2(events):  
    # no longer needed
    # events = np.asarray(events).reshape((Ntrig,Nsamp))

и просто передавать события, как и следовало ожидать.

Однако, если вы не можете изменить подпись SNR2, тогда вы должны позвонить с

SNR2(*event.flat)

внутри mp функция.


Ссылка: Вот отличное объяснение * оператор распаковки и как используется синтаксис при определении функций и вызове функций.

Другие вопросы по тегам