Как найти сумму элементов выше и ниже диагонали матрицы в питоне? - PullRequest
0 голосов
/ 19 ноября 2018

Мне нужно найти сумму элементов, которые находятся выше и ниже основной диагонали.Я понятия не имею, как обусловить алгоритм суммировать только эти числа.Это код, который у меня есть до сих пор, с А, являющимся матрицей

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 голосов
/ 19 ноября 2018

Вот быстрый метод, использующий 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
0 голосов
/ 19 ноября 2018

Вы можете добавить это с 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.

0 голосов
/ 19 ноября 2018

Вы можете использовать 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
0 голосов
/ 19 ноября 2018

Предположим, у вас есть матрица 3х3.

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

Находите ли вы сходство в показателях верхней треугольной и нижней треугольной частей?(Наведите указатель мыши на текстовую часть ниже, чтобы узнать ответ).

Теперь, если вы написали вышеприведенный код самостоятельно, я надеюсь, что вы можете сделать это самостоятельно, так как теперь вы знаете логику.Это будет два цикла (один для обхода строк и один для обхода столбцов) и несколько операторов if.

0 голосов
/ 19 ноября 2018

Ваш первый цикл вычислит сумму диагонали

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]

Итак, хитрости таковы: вычисление суммы для каждого i и j с помощью j > i. Применение тех же трюков для элементов ниже диагонали вычисляет сумму для каждого i и j, с j < i.

for i in range(0, N):
    for j in range(0, i):
        sum3 += A[i][j]
0 голосов
/ 19 ноября 2018

Вот пример, демонстрирующий, как найти сумму в обоих случаях, используя вложенный цикл:

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

Примечание: Учитывайте синтаксис в операторах print, когда вы используете Python 2, а мой ответ - в Python 3.

...