矢量化元素赋值涉及Numpy中矩阵之间的比较

时间:2016-03-23 22:21:06

标签: python numpy matrix vectorization

我正在尝试用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问题,如果有什么不清楚/需要更多细节,请告诉我!感谢。

2 个答案:

答案 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)

好吧,如果你想使用向量运算,你需要使用线性代数来解决问题。我无法为你重新思考这个问题,但我会采取的一般方法是:

  • res =从binedges中减去samplemat
  • res =将res中的值标准化为0和1(使用剪辑?)。即如果&gt; 0,然后是1,否则为0.
  • ncount = sum(res)
  • classifiedMat = res * binedges

等等。