Подтвердить что ты не робот

Как преобразовать блоки в блокдиагональную матрицу (NumPy)

У меня есть три одинаковые квадратные матрицы в NumPy. Я хотел бы объединить их с блочно-диагональной матрицей.

Пример:

a1 = np.array([[1,1,1],[1,1,1],[1,1,1]])
a2 = np.array([[2,2,2],[2,2,2],[2,2,2]])
a3 = np.array([[3,3,3],[3,3,3],[3,3,3]])

r = np.array([[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3]])

Каков наилучший способ сделать это?

4b9b3361

Ответ 1

scipy.linalg имеет функцию block_diag, чтобы сделать это автоматически

>>> a1 = np.array([[1,1,1],[1,1,1],[1,1,1]])
>>> a2 = np.array([[2,2,2],[2,2,2],[2,2,2]])
>>> a3 = np.array([[3,3,3],[3,3,3],[3,3,3]])
>>> import scipy.linalg
>>> scipy.linalg.block_diag(a1, a2, a3)
array([[1, 1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 2, 2, 2, 0, 0, 0],
       [0, 0, 0, 2, 2, 2, 0, 0, 0],
       [0, 0, 0, 2, 2, 2, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 3, 3, 3],
       [0, 0, 0, 0, 0, 0, 3, 3, 3],
       [0, 0, 0, 0, 0, 0, 3, 3, 3]])
>>> r = np.array([[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0],[1,1,1,0,0,0,0,0,0], [0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,2,2,2,0,0,0],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3],[0,0,0,0,0,0,3,3,3]])
>>> (scipy.linalg.block_diag(a1, a2, a3)  == r).all()
True

Ответ 2

Если вам нужен этот конкретный массив r, возможно, самый простой способ:

r=np.kron(np.diag([1,2,3]),np.ones((3,3),dtype='int'))

Если a1, a2, a3 могут быть произвольными двумерными массивами, то, возможно, самый простой способ:

a1=np.asmatrix(a1)
a2=np.asmatrix(a2)
a3=np.asmatrix(a3)
z=np.asmatrix(np.zeros((3,3)))
r=np.asarray(np.bmat('a1, z, z; z, a2, z; z, z, a3'))

Альтернативный более медленный метод:

r=(np.kron([[1,0,0],[0,0,0],[0,0,0]],a1)   
   +np.kron([[0,0,0],[0,1,0],[0,0,0]],a2)
   +np.kron([[0,0,0],[0,0,0],[0,0,1]],a3))