【问题标题】:Combination of matrix elements giving non-zero value (PYTHON)给出非零值的矩阵元素的组合(PYTHON)
【发布时间】:2018-07-19 06:31:18
【问题描述】:

给定两个相当大的矩阵 A、B 和一个非常复杂的函数 F,我必须计算以下表达式: The mathematical expression

我在想是否有一种有效的方法可以首先找到那些在矩阵相乘后会给出非零元素的索引 i,j,这样我就可以避免相当慢的“for 循环”。

当前工作代码

# Starting with 4 random matrices 
A = np.random.randint(0,2,size=(50,50))
B = np.random.randint(0,2,size=(50,50))
C = np.random.randint(0,2,size=(50,50))
D = np.random.randint(0,2,size=(50,50))
indices []
for i in range(A.shape[0]):
    for j in range(A.shape[0]):
        if A[i,j] != 0:
            for k in range(B.shape[1]):
                if B[j,k] != 0:
                for l in range(C.shape[1]):
                    if A[i,j]*B[j,k]*C[k,l]*D[l,i]!=0:
                        indices.append((i,j,k,l))
print indices

如您所见,为了获得我需要的索引,我必须使用嵌套循环(= 巨大的计算时间)。

【问题讨论】:

  • 愿意分享您现有的代码吗?请看minimal reproducible example
  • 您说“矩阵乘法”,但您的表达式看起来不像矩阵乘法...您确定您的索引都正确吗?

标签: python numpy for-loop matrix indices


【解决方案1】:

我的猜测是否定的:你无法避免 for 循环。为了找到所有索引ij,您需要遍历所有违背此检查目的的元素。因此,您应该继续在numpy 中使用简单的数组元素乘法和点积 - 它应该非常快,numpy 负责循环。

但是,如果您打算使用 Python 循环,那么答案是肯定的,您可以使用 numpy 来避免它们,使用以下伪代码 (=hand-waving):

i, j = np.indices((N, M)) # CAREFUL: you may need to swap i<->j or N<->M
fs = F(i, j, z) # array of values of function F
                # for a given z over the index grid
R = np.dot(A*fs, B) # summation over j
# return R # if necessary do a summation over i: np.sum(R, axis=...)

如果问题是计算fs = F(i, j, z) 是一个非常慢的操作,那么您将必须使用numpy 中内置的两个循环来识别A 中为零的元素(因此它们非常快):

good = np.nonzero(A) # hidden double loop (for 2D data)
fs = np.zeros_like(A)
fs[good] = F(i[good], j[good], z) # compute F only where A != 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 2015-05-12
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多