Общий размер массива должен быть неизменным
Я использую модуль 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
функция.
Ссылка: Вот отличное объяснение *
оператор распаковки и как используется синтаксис при определении функций и вызове функций.