Вот один векторизованный подход, использующий broadcasting
и masking/boolean-indexing
-
r = np.arange(dimension)
mask = r[:,None] < r # Or in one step : ~np.tri(dimension,dtype=bool)
matrix[mask] = register
matrix.T[mask] = register
Если вам нужно вычислить dimension
из заданного register
, мы можем использовать:
dimension = int(np.ceil(np.sqrt(2*len(register))))
И для утверждения длины, учитывая dimension
, мы могли бы иметь:
assert dimension*(dimension-1)//2 == len(register)
Кроме того, для производительности рассмотрите возможность подачи в массиве версии register
.
Пробный прогон -
In [43]: import numpy as np
...: dimension = 4 # other matrices' dimensions will be larger
...: matrix = np.zeros((dimension,dimension))
...:
...: register = [11, 12, 13, 23, 24, 34]
In [44]: r = np.arange(dimension)
...: mask = r[:,None] < r
...: matrix[mask] = register
...: matrix.T[mask] = register
In [45]: matrix
Out[45]:
array([[ 0., 11., 12., 13.],
[11., 0., 23., 24.],
[12., 23., 0., 34.],
[13., 24., 34., 0.]])
Как masking
может быть лучше, чем генерация всех треугольных индексов
Генерация индексов заняла бы больше памяти, чем создание логического массива, который по самой своей природе был бы эффективным для памяти и, следовательно, приводил к повышению производительности, особенно для больших массивов. Время на это будет пытаться доказать это -
In [3]: import numpy as np
...: dimension = 5000 # other matrices' dimensions will be larger
...: register = np.random.randint(0,10,dimension*(dimension-1)//2)
# With masking and boolean-indexing
In [4]: %%timeit
...: matrix = np.zeros((dimension,dimension),dtype=int)
...: r = np.arange(dimension)
...: mask = r[:,None] < r
...: matrix[mask] = register
...: matrix.T[mask] = register
10 loops, best of 3: 108 ms per loop
# With triangular indices indexing
In [5]: %%timeit
...: N = dimension
...: matrix = np.zeros((dimension,dimension),dtype=int)
...: idx = np.triu_indices(N, k=1)
...: matrix = np.zeros((N, N))
...: matrix[idx] = register
...: matrix.T[idx] = register
1 loop, best of 3: 364 ms per loop