我正在尝试用Numpy中的矢量化操作替换此代码块中的for循环:
def classifysignal(samplemat, binedges, nbinmat, nodatacode):
ndata, nsignals = np.shape(samplemat)
classifiedmat = np.zeros(shape=(ndata, nsignals))
ncounts = 0
for i in range(ndata):
for j in range(nsignals):
classifiedmat[i,j] = nbinmat[j]
for e in range(nbinmat[j]):
if samplemat[i,j] == nodatacode:
classifiedmat[i,j] == nodatacode
break
elif samplemat[i,j] <= binedges[j, e]:
classifiedmat[i,j] = e
ncounts += 1
break
ncounts = float(ncounts/nsignals)
return classifiedmat, ncounts
但是,我在构思如何替换第三个for循环(即以for e in range(nbinmat[j])
开头的那个循环时遇到了一些麻烦,因为它需要在赋值之前比较两个单独矩阵的各个元素,并使用索引这些元素(i和e)之间是完全分离的。有一种简单的方法可以使用全数组操作来实现这一点,还是坚持使用for循环最好?
PS:我的第一个Stackoverflow问题,如果有什么不清楚/需要更多细节,请告诉我!感谢。
答案 0 :(得分:0)
如果没有一些具体的例子和解释,很难(或至少工作)弄清楚你想要做什么,特别是在内循环中。因此,让我们解决几个问题并尝试简化它们
In [59]: C=np.zeros((3,4),int)
In [60]: N=np.arange(4)
In [61]: C[:]=N
In [62]: C
Out[62]:
array([[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]])
表示classifiedmat[i,j] = nbinmat[j]
可以移出循环
classifiedmat = np.zeros(samplemat.shape)
classifiedmat[:] = nbinmat
和
In [63]: S=np.arange(12).reshape(3,4)
In [64]: C[S>8]=99
In [65]: C
Out[65]:
array([[ 0, 1, 2, 3],
[ 0, 1, 2, 3],
[ 0, 99, 99, 99]])
建议
if samplemat[i,j] == nodatacode:
classifiedmat[i,j] == nodatacode
可以替换为
classifiedmat[samplemat==nodatacode] = nodatacode
我还没有弄清楚loop和break是否修改了这个替换。
内循环的可能模型是:
In [83]: B=np.array((np.arange(4),np.arange(2,6))).T
In [84]: for e in range(2):
C[S<=B[:,e]]=e
....:
In [85]: C
Out[85]:
array([[ 1, 1, 1, 1],
[ 0, 1, 2, 3],
[ 0, 99, 99, 99]])
您还可以将S和B的所有值与:
进行比较In [86]: S[:,:,None]<=B[None,:,:]
Out[86]:
array([[[ True, True],
[ True, True],
[ True, True],
[ True, True]],
[[False, False],
[False, False],
[False, False],
[False, False]],
[[False, False],
[False, False],
[False, False],
[False, False]]], dtype=bool)
您正在迭代:
for e in range(nbinmat[j]):
可能会抛弃所有这些等价物。我不打算弄清楚它的意义。但也许我已经给了你一些想法。
答案 1 :(得分:-1)
好吧,如果你想使用向量运算,你需要使用线性代数来解决问题。我无法为你重新思考这个问题,但我会采取的一般方法是:
等等。