数组的总大小必须保持不变



我正在使用一个名为emcee的Python模块对一个发行版进行采样。我需要传递一个(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的数组吗?

注:在你问为什么我甚至把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

据我所知,events将事件数组分解为37*100个单独的参数。

这不是真的。如果使用

调用mp
mp(SNR2, events)

则在mp中,events将是一个包含1个元素的元组,(arr,),其中arr是(37,100)形状的数组。

如果使用

调用mp
mp(SNR2, *events)

则在mp中,events将是一个包含37个元素的元组,其中37个元素是形状为(37,100)的数组的37行。

如果使用

调用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函数中时会引发错误。

由于SNR2mp中是使用SNR2(event)调用的,而event是一个(37,100)形状的数组,因此SNR2中的event变量是一个包含原始数组的1元素元组。那不是你想要的。

修复代码的最简单方法是定义
def SNR2(events):  
    # no longer needed
    # events = np.asarray(events).reshape((Ntrig,Nsamp))

,并像预期的那样传递事件。

然而,如果你不能改变SNR2的签名,那么你必须用 来调用它。
SNR2(*event.flat)

mp函数内。


参考:这是*解包操作符的一个很好的解释,以及在定义函数和调用函数时如何使用语法。

相关内容

  • 没有找到相关文章

最新更新