[英]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.triu
, np.tril
和np.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_indices
此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。
这是使用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.