【问题标题】:Vectorized element assignment involving comparisons between matrices in Numpy涉及 Numpy 中矩阵之间比较的向量化元素分配
【发布时间】:2016-03-23 22:21:05
【问题描述】:

我目前正在尝试用 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 问题,所以如果有任何不清楚/需要更多详细信息,请告诉我!谢谢。

【问题讨论】:

  • 为什么将第一个“if”语句放在 for loop over range(nbinmat[j]) 中?我看什么都靠e里面的吗?此外,“classifiedmat[i,j] == nodatacode”不应该是“classifiedmat[i,j] = nodatacode”吗?
  • 问题出在 elif 子句中,就像你说的那样。也许这段代码不能完全重写(虽然有些部分可以),但也许“更大的图景”可以?如果您可以阐明您实际想要做什么(binedges 来自哪里,为什么需要将数组的每个元素与可能交错的数组中的元素进行比较),那么也许更多的帮助是可用。

标签: python numpy matrix vectorization


【解决方案1】:

如果没有一些具体的例子和解释,很难(或至少可以)弄清楚你想要做什么,尤其是在内部循环中。所以让我们解决几个部分并尝试简化它们

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

可能会丢弃所有这些等价物。我不会试图弄清楚它的重要性。但也许我给了你一些想法。

【讨论】:

  • 感谢您的帮助!它绝对给了我一些想法。
【解决方案2】:

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

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

等等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 2011-08-24
    • 2013-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多