Python 涉及Numpy中矩阵之间比较的向量化元素分配

Python 涉及Numpy中矩阵之间比较的向量化元素分配,python,numpy,matrix,vectorization,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

我目前正在尝试用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循环(即rangenbinmat[j]中以e开头的for循环)时遇到了一点困难,因为它需要在赋值之前比较两个独立矩阵的各个元素,这些元素I和e的索引彼此完全解耦。有没有一种简单的方法可以使用整个数组操作来实现这一点,还是坚持使用for循环最好


PS:我的第一个Stackoverflow问题,所以如果有什么不清楚/需要更多细节,请让我知道!谢谢。

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

res=从边中减去samplemat res=将res中的值规格化为0,并使用clip?将其设置为1?。i、 e如果>0,则为1,否则为0。 ncount=总和res classifiedMat=res*binedges
等等。

如果没有一些具体的例子和解释,就很难或至少很难弄清楚你想做什么,特别是在内部循环中。因此,让我们处理一些问题,并尝试简化它们

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

暗示

if samplemat[i,j] == nodatacode:
   classifiedmat[i,j] == nodatacode
可以用

classifiedmat[samplemat==nodatacode] = nodatacode
我还没有弄清楚循环和中断是否会修改这个替换

内环的一个可能模型是:

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]])

可能会抛弃所有这些等价物。我不想试图弄明白它的意义。但也许我已经给了你一些想法。

为什么要在rangenbinmat[j]上的循环中放入第一个if语句?我看到里面没有依赖于e的东西?此外,classifiedmat[i,j]==nodatacode难道不应该被classifiedmat[i,j]=nodatacode吗?正如你所说,问题确实在elif子句中。也许这段代码无法完全重写,但有些部分可以,但也许更大的图景可以?如果您可以了解您实际想要做什么,binedgescome来自何处,为什么需要将数组中的每个元素与交错数组中的元素进行比较,那么可能会有更多帮助。谢谢您的帮助!这无疑给了我一些可以合作的想法。
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]])
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]):