Преобразование списка, содержащего элементы ниже диагонали матрицы, в полную матрицу
Я хочу создать полноценную матрицу из списка элементов, которые находятся ниже диагонали. Следующий список содержит элементы под диагональю:
И это будет желаемый результат:
До этого момента я пытался заставить это работать с обычным синтаксисом в python, реализовав следующий код:
list_similarities = [1,0.1,0.6,0.4,1,0.1,0.2,1,0.7,1]
the_range = range(0,4)
list_of_lists = []
counter_element = 0
counter = -1
for element in the_range:
counter += 1
counter_element += len(the_range)-element
intermediary = (len(the_range)-element)
first_element = counter_element-intermediary
line_list = list_similarities[first_element:counter_element]
# counter = 0, then no need to add an additional element
# print(line_list)
if counter == 0:
"do nothing"
elif counter >0:
for item in range(0,element):
from_list_to_add = list_of_lists[item]
element_to_add = from_list_to_add[item+1]
line_list.insert(0,element_to_add)
print(line_list)
list_of_lists.append(line_list.copy())
# print("final lists:", list_of_lists)
# print(counter_element)
print("final lists:", list_of_lists)
Тем не менее, вывод следующий:
окончательные списки: [[1, 0,1, 0,6, 0,4], [0,1, 1, 0,1, 0,2], [0,1, 0,1, 1, 0,7], [0,7, 0,1, 0,1, 1]]
Он делает первые 2 списка, которые представляют 2 строки из матрицы, но не будут делать последние 2 из-за того, как работает мой код, и пока я не знаю решения для этого..
Это связано с тем, что мой счетчик сделает список вне диапазона. Я просмотрел множество сообщений о переполнении стека, но не могу найти что-то, что будет работать в моей ситуации. Если вы можете указать мне на подобный пример, это было бы идеально.
Спасибо за ваше время и предложения!
ОБНОВЛЕНИЕ: Мой вопрос не является дубликатом Numpy: преобразовать массив в треугольную матрицу, потому что я не хочу создавать матрицу, где мои значения из массива являются частью только нижней треугольной матрицы, а скорее они также находятся в верхней треугольная матрица.
2 ответа
Решение с использованием numpy.triu_indices
а также numpy.tril_indices
, Я руководил каждым шагом с комментариями. Ключ должен сначала найти верхние правые индексы, назначить значение из списка, а затем сделать матрицу симметричной.
import numpy as np
n = 4
l = [1,0.1,0.6,0.4,1,0.1,0.2,1,0.7,1]
a = np.zeros((n,n)) # Initialize nxn matrix
triu = np.triu_indices(n) # Find upper right indices of a triangular nxn matrix
tril = np.tril_indices(n, -1) # Find lower left indices of a triangular nxn matrix
a[triu] = l # Assign list values to upper right matrix
a[tril] = a.T[tril] # Make the matrix symmetric
print(a)
Выход
[[1. 0.1 0.6 0.4]
[0.1 1. 0.1 0.2]
[0.6 0.1 1. 0.7]
[0.4 0.2 0.7 1. ]]
Это очень просто с помощью numpy.triu_indices_from
,
Использовать этот:
import numpy as np
list_similarities = [1,0.1,0.6,0.4,1,0.1,0.2,1,0.7,1]
n = 4
Full_matrix = np.zeros((n,n))
inds = np.triu_indices_from(Full_matrix, k = 0)
# use [:] to copy the list and avoid any problem if the initial list is further needed
Full_matrix[inds] = list_similarities[:]
Full_matrix[(inds[1], inds[0])] = list_similarities[:]
Результаты
array([[1. , 0.1, 0.6, 0.4],
[0.1, 1. , 0.1, 0.2],
[0.6, 0.1, 1. , 0.7],
[0.4, 0.2, 0.7, 1. ]])
PS: Подробнее о причине, по которой я копирую список, используя list_similarities[:]
Вот