bnds = [(0, 0) if i == j else (0, None) for _ in range(2) for i in range(d) for j in range(d)]
Приведенный выше код предназначен для размера матрицы dxd. Приведенный выше код предназначен для того, чтобы все диагональные элементы матрицы были равны нулю. Для всех остальных записей мы просто устанавливаем любое число (0, None), которое, как я полагаю, является любым неотрицательным числом.
Теперь мне нужно изменить приведенный выше код. Исходная матрица — dxd. Теперь у меня есть матрица Kd x Kd, где каждый d имеет блочную матрицу KxK. Для этой большой матрицы Kd x Kd мне нужно, чтобы вся диагональная блочная матрица KxK была нулевой матрицей.
Например, скажем, d=20 и K=5. Тогда матрица первых 5 строк и первых 5 столбцов должна быть нулевой. Матрица [6:10, 6:10] также должна быть нулевой матрицей и т.д.
В R я знаю, что индексы
index0 = ((j - 1) * K + 1) : (j * K)
index1 = ((l - 1) * K + 1) : (l * K)
Но в Python начальный и конечный индекс различны. Я не уверен, правильна ли моя попытка. Моя текущая попытка:
bnds = []
for i in range(1, K*d+1):
for j in range(1, K*d+1):
block_row = (i - 1) // K
block_col = (j - 1) // K
row_start = block_row * K + 1
row_end = row_start + K
col_start = block_col * K + 1
col_end = col_start + K
if block_row == block_col:
bnds.append((0, 0))
else:
bnds.append((0, None))
Я новичок в Python. Пожалуйста, прокомментируйте мой приведенный выше код. Спасибо.
Вы не используете начало и конец, поэтому они не могут быть неправильными...
Выберите (достаточно маленькие) K и d. Что вы ожидаете получить за эти ценности? Что вы получаете, когда запускаете свой код?
@Julien В Python для числа в диапазоне (5): print(num) Возвращает 0,1,2,3,4. В него не входит 5
Так? range(1,5+1)
— это 1,2,3,4,5
, и после того, как вы вычтете 1
из каждого элемента, оно снова станет 0,1,2,3,4
...
@ Жюльен, я понимаю. Ты прав. Как изменить мой код?
Я вам буквально уже сказал в первом комментарии? и, конечно, затем используйте i
вместо i-1
... (Обратите внимание, что вам не нужно ничего менять, оба эквивалентны, это просто приятнее и питоничнее)
Мне трудно понять, что вы пытаетесь сделать. «Тогда матрица первых 5 строк и первых 5 столбцов должна быть нулевой матрицей. Матрица [6:10, 6:10] также должна быть нулевой матрицей и т. д.» Какие матрицы не должны быть нулевыми?
@Barmar Все, что не является диагональной блочной матрицей, не является нулевой матрицей.
А, теперь я это вижу: [0:6, 6:10], [6:10, 6:10], ...
@Бармар, точно! При d=20 и K =5. Для матрицы 100x100 мне нужны все 20 диагональных блоков [1:5, 1:5], [6:10, 6:10],...,[96:100 , 96:100] (извините, мне больше знаком обычный индекс от матрицы и R) — это нулевая матрица.
Самый простой способ — сначала создать ненулевую матрицу, а затем заменить эти диагональные подматрицы нулями, вместо того, чтобы пытаться сделать все это за один цикл.
@Бармар, я понимаю. Не могли бы вы дать мне ответ?
Начните с ненулевой матрицы Kd x Kd:
side_size = K * d
bnds = [(0, None) for i in range(side_size) for j in range(side_size)]
Затем используйте вложенные циклы, чтобы заменить диагональные подматрицы нулями.
for k in range(0, side_size, K): # k = top-left corner of sub-matrix
for i in range(k, k+K):
for j in range(k, k+K):
bnds[i * side_size + j] = (0, 0)
Я думаю, что в вашем вопросе есть несколько заблуждений, но я постараюсь ответить настолько хорошо, насколько смогу. В приведенном вами примере кода матрица хранится в виде совершенно плоского списка элементов, что я не совсем уверен, что вам это нужно.
Если вы хотите создать 2D-матрицу, вы можете использовать следующий код.
matrix = [[(0,0) if row // k == col // k else (0,None) for col in range(d*k)] for row in range(d*k)]
Однако, если все ваши данные структурированы в виде блоков K x K, я бы рекомендовал использовать 4D-матрицу (что становится намного проще, если вы используете numpy). После установки вы можете использовать следующий код, который по сути создает ту же матрицу, что и выше, но с другой структурой. В этом случае матрица будет матрицей размера d x d из матриц k x k.
import numpy as np
matrix = np.full(shape=(d, d, k, k, 2), fill_value=(0,None))
matrix[range(d), range(d)] = np.full(shape=(k, k, 2), fill_value=(0,0))
Если по какой-то причине вы действительно хотели представить матрицу как совершенно плоский одномерный список, вы можете просто изменить понимание списка следующим образом.
flat_matrix = [(0,0) if row // k == col // k else (0,None) for col in range(d*k) for row in range(d*k)]
Я предполагаю, что это будет чем-то использовано, и каждый элемент в матрице представляет собой числовые границы. Таким образом, (0, 0) фиксирует значение на нуле, а (0, None) не имеет верхней границы.
Ах, это имеет больше смысла! Не понял, что bnds, вероятно, означает «границы». Я отредактирую ответ.
зачем использовать
for i in range(1, K*d+1)
, чтобы затем использоватьi-1
? Просто используйтеfor i in range(K*d)
.