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

时间:2018-11-19 15:44:10

标签: python arrays numpy matrix diagonal

我需要找到主对角线上方和下方的元素之和。我不知道如何调整算法的总和。这是我到目前为止的代码,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

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

6 个答案:

答案 0 :(得分:1)

您可以使用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

答案 1 :(得分:0)

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

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中。

答案 2 :(得分:0)

您的第一个循环将计算对角线的总和

for i in range(0, N):
    sum += A[i][i]

第二个循环将完成此工作,并计算对角线以上每个元素的总和!

for i in range(0, N):
    for j in range(i+1, N):
        sum2 += A[i][j]

因此,窍门是:使用j > i计算每个i和j的总和。 对角线以下的元素应用相同的技巧是使用j < i计算每个i和j的总和。

for i in range(0, N):
    for j in range(0, i):
        sum3 += A[i][j]

答案 3 :(得分:0)

让我们假设您有一个3x3矩阵。

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

在上三角形和下三角形部分的索引中是否找到相似之处? (将鼠标悬停在下面的文本部分上即可知道答案)。

  

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

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

答案 4 :(得分:0)

您可以使用numpy.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。

答案 5 :(得分:0)

这里是一种快速方法,对三角形使用>>> JSONRenderer().render(serializer.data) b'{"date_added":"2018-11-19T21:10:29.324522Z","start_date":"2018-11-15T05:36:10Z","data":"{\\"resource_state\\":3,\\"athlete\\":{\\"id\\":3255732,\\"resource_state\\":1},\\"name\\":\\"Morning Ride\\",\\"distance\\":33605.0, ,对角线使用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