繁体   English   中英

如何在python中找到矩阵对角线上方和下方的元素总和?

[英]How to find the sum of elements above and below the diagonal of a matrix in python?

我需要找到主要对角线上方和下方的元素的总和。 我不知道如何调整算法的总和。 这是我到目前为止的代码,其中A为矩阵

A = []
N = int(raw_input("Input matrix size: "))
for i in range(0, N):
    row = []
    for j in range(0, N):
        row.append(int(raw_input("Input elements: ")))
    A.append(row)
sum = 0
for i in range(0, N):
    sum += A[i][i]
print sum       
sum2 = 0
for i in range(0, N):
    for j in range(i+1, N):
        sum2 += A[i][j]
print sum2

我猜我应该为语句使用更多。 谢谢

这是一个示例案例,展示了如何使用嵌套循环在两种情况下都求和:

matrix = [[i+j for j in range(4)] for i in range(4)]

for row in matrix:
    print(" ".join(list(map(str,row))))

totalSum = 0
for i in range(1,len(matrix)):
    for j in range(i):
        totalSum += matrix[i][j]
print("Below sum: ", totalSum)

totalSum = 0
for i in range(len(matrix)):
    for j in range(i+1,len(matrix)):
        totalSum += matrix[i][j]
print("Above sum: ", totalSum)

输出:

0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
Below sum:  18
Above sum:  18

您还可以使用以下一线:

对角线以下:

totalSum = sum([matrix[i][j] for i in range(1,len(matrix)) for j in range(i)])

对角线上方:

totalSum = sum([matrix[i][j] for i in range(len(matrix)) for j in range(i+1,len(matrix))])

如果要对主对角线上方和下方的所有数字求和,可以执行索引检查:

totalSum = 0
for i in range(len(matrix)):
    for j in range(len(matrix)):
        if not i==j:
            totalSum += matrix[i][j]
print("Sum: ", totalSum)

然而,找到该总和的另一种方法(尽管不推荐)是找到矩阵的总和与主对角线的总和,然后进行减法以找到最终的总和:

matrix = [[i+j for j in range(4)] for i in range(4)]

for row in matrix:
    print(" ".join(list(map(str,row))))

matrixSum = sum([sum(elem for elem in row) for row in matrix])
diagonalSum = sum([matrix[i][i] for i in range(len(matrix))])
finalSum = matrixSum - diagonalSum

print("Matrix sum: ", matrixSum)
print("Diagonal sum: ", diagonalSum)
print("Final sum: ", finalSum)

输出:

0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6

Matrix sum:  48
Diagonal sum:  12
Final sum:  36

注意:在使用Python 2时, 请注意 print语句中的语法,而我的答案是在Python 3中。

您可以使用np.triunp.trilnp.trace来计算这些总和(您的问题未指定是否允许您使用numpy ):

import numpy as np

np.random.seed(0)
A = np.random.randint(0,10,size=(5,5))

给出:

[[5 0 3 3 7]
 [9 3 5 2 4]
 [7 6 8 8 1]
 [6 7 7 8 1]
 [5 9 8 9 4]]

然后:

upper_sum = np.triu(A).sum()-np.trace(A)
lower_sum = np.tril(A).sum()-np.trace(A)

产量:

34
73

假设您有一个3x3矩阵。

[[a11, a12, a13],
 [a21, a22, a23],
 [a31, a32, a33]]

您在上三角部分和下三角部分的索引中发现任何相似之处吗? (将鼠标悬停在下面的文本部分上即可知道答案)。

与第二索引相比,上三角的第一索引的值较低。 同样,下三角中的第一个索引小于第二个索引。 而且,对于对角线元素,索引是相同的!

现在,假设您自己编写了上面的代码,我希望您可以自己做一个,因为您现在知道逻辑了。 这将是两个循环(一个循环遍历行,一个循环遍历列),以及一些if语句。

您可以使用numpy.triu_indicesnumpy.triu_indices 我在每个步骤的下方进行了评论,以指导您完成此步骤。 基本上,您可以使用numpy.triu_indices获得右上角的索引,并在它们上循环以获取元素。 您将除对角线上的所有元素相加。

import numpy as np

m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
triu = np.triu_indices(m.ndim+1) # Get upper right indices of m
triu_idx = list(zip(triu[0],triu[1])) # List of tuples for the upper right indices
cum_sum = 0 # Initialize sum
for x in triu_idx: # Loop over the upper right indices
  if x[0] != x[1]: # Exclude diagonal elements
    cum_sum += m[x] # Add to sum

print(cum_sum) # Output 11

给定矩阵

[[1 2 3]
 [4 5 6]
 [7 8 9]]

输出11。

这是使用scipy.spatial.distance.squareform的三角形和np.einsum的对角线的快速方法:

>>> import numpy as np
>>> from scipy.spatial.distance import squareform
>>> 
>>> x = np.arange(36).reshape(6, 6)
>>>
>>> sum_ut = squareform(x, checks=False).sum()
>>> sum_dg = np.einsum('ii', x)
>>> sum_lt = squareform(x.T, checks=False).sum()

时间:

>>> timeit(lambda: squareform(x, checks=False).sum())
6.272806407185271
>>> timeit(lambda: np.einsum('ii', x))
1.3961836302187294
>>> timeit(lambda: squareform(x.T, checks=False).sum())
6.6827554509509355

为了比较:

>>> timeit(lambda: np.triu(x, 1).sum())
13.85556498519145
>>> timeit(lambda: np.trace(x))
3.081781509099528
>>> timeit(lambda: np.tril(x, -1).sum())
13.659938262077048

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM