矩阵对角线元素之和

27
我正在尝试找出矩阵对角线元素的总和。这里,n是方阵的大小,a是矩阵。有人可以解释一下这里发生了什么吗?
n = 3
a = [[11,2,4],[4,5,6],[10,8,-12]]
sum_first_diagonal = sum(a[i][i] for i in range(n))
sum_second_diagonal = sum(a[n-i-1][n-i-1] for i in range(n))
print(str(sum_first_diagonal)+" "+str(sum_first_diagonal))

你正在两次求和同一条对角线,一次是从左上到右下,另一次是相反的方向。我不相信这段代码片段在任何Python安装中都能打印出除了“4 4”之外的任何内容。 - Sven Marnach
18个回答

25

使用numpy库进行矩阵计算,该库在任何矩阵计算方面都非常强大。对于您的特定情况:

import numpy as np
a = [[11,2,4],[4,5,6],[10,8,-12]]
b = np.asarray(a)
print('Diagonal (sum): ', np.trace(b))
print('Diagonal (elements): ', np.diagonal(b))

你可以使用pip或者其他方式在很多网站上轻松安装numpy。

如果想要获取所有的对角线而不仅仅是主对角线,请查看此处,它也使用了numpy。

编辑

如果要计算反对角线(次对角线),按照维基百科中说明,您可以在numpy中翻转矩阵。

import numpy as np
a = [[11,2,4],[4,5,6],[10,8,-12]]
b = np.asarray(a)
b = np.fliplr(b)
print('Antidiagonal (sum): ', np.trace(b))
print('Antidiagonal (elements): ', np.diagonal(b))

我认为OP无法使用 numpy,因为他们正在将代码提交给不允许使用 numpy 的在线评测系统。第二条对角线是如何计算的? - mhawke

21

尝试这个方法来求解矩阵的次对角线之和:

sum(a[i][n-i-1] for i in range(n))

内部循环访问这些条目:

>>> n = 3
>>> [(i, n-i-1) for i in range(n)]
[(0, 2), (1, 1), (2, 0)]

你的样本矩阵对角线上的数值总和为:

>>> n = 3
>>> sum(a[i][n-i-1] for i in range(n))
19

你代码中的错误是在两个维度上使用了相同的表达式:

a[n-i-1][n-i-1]

这将以相反的顺序重新处理第一个对角线[(2, 2), (1, 1), (0, 0)],并使得您获得两次相同的总和。


1

这里有一种更简单的方法来获取完整的主对角线次对角线

squared_matrix = [
    [2, 3, 4],
    [4, 3, 3],
    [3, 3, 4]
]


def primary_diagonal(matrix):
    sum = 0
    for i in range(len(matrix)):
        sum += matrix[i][i]
    return sum

def secondary_left_diagonal(matrix):
    sum = 0
    for i in range(len(matrix)):
        sum += matrix[i][len(matrix) - i - 1]
    return sum


print(primary_diagonal(squared_matrix))
print(secondary_left_diagonal(squared_matrix))

结果

9
10

1
从一个平方矩阵中获取总和和对角线和
squared_matrix = [[2,3,4],[4,3,3],[3,3,4]]
s, ds = get_sum(squared_matrix)

def get_sum(diag_mat):
    n = len(diag_mat)
    total = sum([diag_mat[i][j] for i in range(n) for j in range(j)]
    d_sum = sum([diag_mat[i][j] if i==j else 0 for i in range(n) for j in range(j)]
   return d_sum, total

0

试试这个:

n=3
sum_second_diagonal=sum([a[i][j] for i in range(n) for j in range(n) if i==j]) #it will add when i==j

0

假设你有一个矩阵 A n×m。

  A = [[random.rand() for i in range(n+1)] for i in range(m+1)]
  
  d = m+n-1 # that's the overall number of different diagonals
  sumrow = [0]*d # I'd like to create a list of all the sums of those
  for diag in range(d): # iterate by diagonal number
      # A difference of two related spike functions, so that it was a spike without the top
      diaglength = int(max(0,1+d/2-abs(diag+1/2-d/2)) - max(0,1+d/2-n-abs(diag+1/2-d/2)))
      # initial coordinates for further iteration inside sum() function
      x = max(0, diag-m+1)
      y = max(0, m-diag-1)
      # iterating values along the current diagonal
      sumrow[diag]=sum(A[x+i][y+i] for i in range(0,diaglength))

因此,sumrow[]是每个对角线的总和列表,选择并不会混淆。我认为,很明显可以从这段代码中剪切掉一些内容以立即获得特定值。

技术上讲,这段代码可以压缩成一行。非常长的一行。

但是为什么呢?


0
假设有一个方阵(nxn),您可以通过仅迭代矩阵的行来计算主对角线和次对角线的总和;通过跟踪每个计算中涉及的索引。
mat = [
    [1,2,3],
    [4,5,6],
    [9,8,9]
]

primary = 0
secondary = 0
low = 0 # start index for primary
high = len(mat)-1 # end index for secondary

for row in mat:
    primary += row[low]
    secondary += row[high]
    low += 1
    high -= 1

print(f'Primary Sum = {primary}', f'Secondary Sum = {secondary}', sep='\n')

0

以下是一种实现方法:

由于矩阵是方阵,我们可以使用原始列表和反转列表来获取对角线和反对角线的总和。

matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

to_sum =[]                             # an empty list for collection values

for i in range(len(matrix)):           # diagonal coordinats [0][0], [1][1].... [n][n]
    to_sum.append(matrix[i][i])        # append value of diagonal
    rev = matrix[i][::-1]              # for anti-diagonal reverse list
    to_sum.append(rev[i])              # append value of anti-diagonal
                                       # to_sum list [1, 4, 6, 7, 11, 10, 16, 13]
return sum(to_sum)                     # return sum of all values in list (68)

0
//we simply swap  corner elements of matrix

def diagonalDifference(arr):

    c=0;d=0
    for i in range(len(arr)):
        for j in range(len(arr)):
            if i==j :
                c = c+ arr[i][j]
        for k in range(len(arr)):
            arr[i][k-1],arr[i][k-2] = arr[i][k-2],arr[i][k-1]
        

        for j in range(len(arr)):
            if i==j :
                d = d + arr[i][j]
        for k in range(len(arr)):
            arr[i][k-1],arr[i][k-2] = arr[i][k-2],arr[i][k-1]
            
    
    
    print(c,d)  
    result = abs(c-d)
    print(result)

欢迎来到Stack Overflow。没有任何解释的代码转储很少有帮助。Stack Overflow是关于学习的,而不是提供盲目复制和粘贴的片段。请[编辑]您的问题并解释它如何回答特定的问题。请参见[答案]。当回答旧问题(这个问题已经5.5年了)时,这尤其重要,因为已经有现有的答案。 - Chris

0
Python 3动态输入矩阵列表的解决方案
#Even matrix size is dynamic in this code as "n".

n=int(input())
s1=0
s2=0
a =[]
for i in range(n):

    # x here take input of size n and as separate lists to act like a matrix.

    x=list(map(int,input().strip().split()))[:n]
    a.append(x)
for i in range(n):
    s1+=a[i][i]
    s2+=a[i][n-i-1]

# If use abs() only if non-negative output is needed!!
print(abs(s1-s2)) 
# First enter the size of matrix then enter the matrix vales with spaces in each line

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接