变维数组的Python方法
这是一个简单的问题,但我找不到“最佳实践”,我想知道是否有比许多if语句更简单的方法。假设我有一个方法,它接受一个变量'data',它的形状是(N,M),其中N可以变化。具体来说,有时数据是形状(M,)的一维数组,其他时间N=100,例如数据是形状(100,M) 下面是当N>1时该方法的基本代码。当N>1或N可以等于1(或者最好是data.shape=(M,)而不仅仅是(1,M))时,我如何将其用于一般情况?我可以放很多if语句,但我希望有一个更干净的解决方案变维数组的Python方法,python,numpy,Python,Numpy,这是一个简单的问题,但我找不到“最佳实践”,我想知道是否有比许多if语句更简单的方法。假设我有一个方法,它接受一个变量'data',它的形状是(N,M),其中N可以变化。具体来说,有时数据是形状(M,)的一维数组,其他时间N=100,例如数据是形状(100,M) 下面是当N>1时该方法的基本代码。当N>1或N可以等于1(或者最好是data.shape=(M,)而不仅仅是(1,M))时,我如何将其用于一般情况?我可以放很多if语句,但我希望有一个更干净的解决方案 #start with varia
#start with variables data.shape=(N,M), vol.shape=(M,), jstarts and jends .shape=(4,)
N=3
#N=1 #uncomment to test
M=20
jstarts = np.array([0,5,12,15])
jends = np.array([3,10,14,18])
data = np.arange(0,N,M).reshape(N,M)
data_new = np.empty((N,M))
for i in range(0,N):
for j in range(0,jstarts.size):
jstart = jstarts[j]
jend = jends[j]
tmp = np.sum(data[i,jstart:jend]*vol[jstart:jend])/np.sum(vol[jstart:jend])
data_new[i,jstart:jend] = tmp
*注意:jstart和jend依赖于j,但不依赖于i我已经花了很多时间在numpy上了,但是IIRC,您应该能够通过使用
省略号来删除至少外部循环:
for j in range(10):
jstart = jstarts[j]
jend = jends[j]
tmp = np.sum(data[...,jstart:jend]*vol[jstart:jend], axis=1)/np.sum(vol[jstart:jend])
data_new[..., jstart:jend] = tmp
对于范围内的i(…):对于范围内的j(…):do_sth()
不是,而numpy的特殊优势在于使操作快速且富有表现力。我简化了代码,并添加了细节。这是从实际代码中简化出来的(jstart和jend是复杂的np.where()的替代品)。我知道循环的范围不是很像蟒蛇。也许我应该重构一下。我认为更新后的代码可以简单地使用einsum和基于N==1或不基于N==1的字符串的if语句来完成。仍然有一个嵌套循环。循环的范围非常Pythonic。是numpy
提供了替代方案,通常用于可以并行完成的事情。但是有些问题本质上是串行的。如果没有样本值-N,M,data,vol,jstart,jend-,我认为这个问题应该结束。如果您需要帮助,请使其易于理解和测试。啊,我知道省略号,但没有意识到np.sum()可以这样操作(我想我必须使用einsum)。我认为这解决了眼前的问题,谢谢。或者,也许len(data.shape)-1
?这实际上不起作用,在最初的文章中,np.sum()生成一个值,该值被复制到索引jstart:jend中的data\u新数组中。有了省略号,tmp应该生成一个1d,shape[Nt,1]数组,然后将其放入shape[Nt,jend jstart+1]空间中的新数据中,因此我认为必须手动复制1darray@Michael--正如我所说,我已经有一段时间没有对努比做太多了。你能np.sum(data[…,jstart:jend].ravel())
吗?谢谢你的帮助。.ravel只会展平数据并生成标量,但实际上通常生成的1d数组具有不同的值,需要复制。我想我必须咬紧牙关,输入一个if语句来执行tmp=(tmp[np.newaxis,…])。如果N>1,重复(N,axis=0)