Заполнение 1D массивов в 3D векторизацию массивов - PullRequest
0 голосов
/ 11 марта 2020

У меня есть функция init_tensor(), которая транслирует 2-мерную матрицу измерения (N,N) в 3-мерную блочную матрицу dim (M,N,N), так что существует M матриц измерения NXN:

def init_tensor(input_state, sample_size):
    return np.broadcast_to(input_state, (sample_size,)+input_state.shape)

Так, например, если я хочу создать 3 (4x4) матрицы, я мог бы сделать:

init_tensor(np.eye(4, dtype=complex), 3)
Out[462]: 
array([[[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]],

       [[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]],

       [[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
        [0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j]]])

У меня проблема в том, что у меня есть несколько массивов с dim (1, M), которые я хотел бы заполнить 3D-массив в качестве его элементов. Для простого случая, если М было 3 и у меня есть:

lambda1 = [l11,l12,l13]
lambda2 = [l21,l22,l23]
lambda3 = [l31,l32,l33]
tau1 = [t11,t12,t13]
tau2 = [t21,t22,t23]
tau3 = [t31,t32,t33]

Я бы хотел векторизованный способ, где я могу заполнить их в тензор так, чтобы он стал:

array([[[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [   t11,    l11, 0.+0.j, 0.+0.j],
        [   t21, 0.+0.j,    l21, 0.+0.j],
        [   t31, 0.+0.j, 0.+0.j,    l31]],

       [[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [   t12,    l12, 0.+0.j, 0.+0.j],
        [   t22, 0.+0.j,    l22, 0.+0.j],
        [   t32, 0.+0.j, 0.+0.j,    l32]],

       [[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
        [   t13,    l13, 0.+0.j, 0.+0.j],
        [   t23, 0.+0.j,    l23, 0.+0.j],
        [   t33, 0.+0.j, 0.+0.j,    l33]]])

Глубина тензорной матрицы всегда будет равна длине одномерных массивов, и значение M может варьироваться от 1 до 100.

1 Ответ

0 голосов
/ 12 марта 2020

Вы можете использовать numpys расширенное индексирование , чтобы получить этот результат:

import numpy as np

m = 3
n = 4
arr = np.ones((m, n, n), dtype=int)

lmbda = 10 * np.arange(1, (n-1)**2+1).reshape(n-1, n-1)
# lmbda = [[l11,l12,l13]
#          [l21,l22,l23]
#          [l31,l32,l33]]
# array([[10, 20, 30],
#        [40, 50, 60],
#        [70, 80, 90]])
tau = -10 * np.arange(1, (n-1)**2+1).reshape(n-1, n-1)
# array([[-10, -20, -30],
#        [-40, -50, -60],
#        [-70, -80, -90]])

arr[:, range(1, n), range(1, n)] = lmbda.T
arr[:, range(1, n), 0] = tau.T  # arr[:, 1:, 0] = tau.T  # alternative
# array([[[  1,   1,   1,   1],
#         [-10,  10,   1,   1],
#         [-40,   1,  40,   1],
#         [-70,   1,   1,  70]],
#        [[  1,   1,   1,   1],
#         [-20,  20,   1,   1],
#         [-50,   1,  50,   1],
#         [-80,   1,   1,  80]],
#        [[  1,   1,   1,   1],
#         [-30,  30,   1,   1],
#         [-60,   1,  60,   1],
#         [-90,   1,   1,  90]]])
...