У меня проблемы с выполнением следующей операции матрицы. Начиная с квадратной матрицы (двумерный массив) и групп, которые охватывают каждый индекс матрицы (словарь: ключи - это группы, значения - это списки индексов матрицы в группе), мне нужно получить новую меньшую матрицу, которая содержит сумму элементов в каждой подматрице исходной матрицы. Подматрицы определяются в соответствии с индексами групп. Поэтому новая матрица также будет квадратной, но с количеством групп в качестве ее размеров.
Давайте рассмотрим следующий пример:
import numpy as np
X = np.arange(49).reshape((7, 7))
d = {0: [0, 1], 1: [2, 3, 4], 2: [5, 6]}
def get_new_matrix(matrix, groups_indexes):
groups_number = len(groups_indexes)
new_matrix = np.zeros((groups_number, groups_number))
for i in range(groups_number):
for j in range(groups_number):
new_matrix[i][j] = np.sum(matrix[groups_indexes[i]][:,groups_indexes[j]])
return new_matrix
Z = get_new_matrix(X, d)
print(Z)
[[ 16 39 36]
[129 216 159]
[156 249 176]]
Глядя на результат, например, во (второй) строке 1 и (третьем) столбце 2, мы видим, что результат равен 159, это:
Z[1,2]
Это означает, что в исходной матрице подматрица, определенная группами 1 в строках и 2 в столбцах, это строки 2, 3 и 4 и столбцы 5 и 6, явно:
X[[2, 3, 4]][:,[5, 6]]
, а сумма всех элементов в подматрице равна 19 + 20 + 26 + 27 + 33 + 34 = 159.
явно:
np.sum(X[[2, 3, 4]][:,[5, 6]])
Есть ли способ написать более питонический код, избегая двух циклов for для получения новой матрицы и повышая общую эффективность? Полагаю, это должно быть что-то вроде необычного индексирования, вещания и т. Д. , но я не смог найти лучшего решения.
Мой текущий код ужасно масштабируется для больших начальных матриц (и потенциально большого начального числа групп), и, поскольку я буду запускать его не только для произвольных больших начальных квадратных матриц, но и на многих итерациях, мне действительно нужно улучшить Это. Или, может быть, нет способа улучшить код, и объяснение будет очень полезно:)