Python Concatenate и стек многих матриц

Я хочу создать квадратную матрицу, подобную этой, где ее элементом является квадратная матрица либо квадратная матрица B или отрицательная единичная матрица или нули. Я создал матрицу B, а также -I, а также создал матрицу Z из нулей. Матрицы квадратов B, I и Z с одинаковыми размерами n1 * n1 (или n2 * n2) и конечной матрицей, которую я хочу иметь размерами n * n, где n = n1 * n2

Если, например, B, I и Z равны 4*4, финал будет 16*16.

Я знаю, как объединять и складывать матрицы, но я не знаю, как лучше это реализовать, так как нужно сделать приведенный ниже процесс 64! раз.

for iter in range(64):
if iter == 0:
    temp = B
    temp = np.hstack((temp, I))
    temp = np.hstack((temp, Z))
    temp = np.hstack((temp, Z))
if iter == 1:
    temp2 = I
    temp2 = np.hstack((temp2, B))
    temp2 = np.hstack((temp2, I))
    temp2 = np.hstack((temp2, Z))
if iter == 2:
    temp3 = Z
    temp3 = np.hstack((temp3, I))
    temp3 = np.hstack((temp3, B))
    temp3 = np.hstack((temp3, I))
if iter == 3:
    temp4 = Z
    temp4 = np.hstack((temp4, Z))
    temp4 = np.hstack((temp4, I))
    temp4 = np.hstack((temp4, B)) 
    .......
    ........
    ........

st1 = np.vstack((temp, temp2))
st2 = np.vstack((st1, temp3))
.......

Могу ли я сохранить матрицы n * n в элементы массива, а затем объединить или сложить их?


person Er1Hall    schedule 14.03.2019    source источник
comment
То, что вы ищете, - это блочная матрица теплиц, взгляните на матрица теплиц матрицы матрицы теплица < /а>   -  person user2699    schedule 14.03.2019


Ответы (2)


В зависимости от того, имеете ли вы дело с numpy массивами или списками, вы можете использовать следующий пример для добавления массивов:

import numpy as np
x = np.array([[11.1, 12.1, 13.1], [21.1, 22.1, 23.1]])
print(x.shape)
y = np.array([[11.2, 12.2],[21.2, 22.2]])
print(y.shape)
z = np.append(x,y, axis=1)
print(z.shape)
print(z)

Обратите внимание, что, как упоминалось @user2699, добавление numpy может замедляться для больших размеров массива (Самый быстрый способ увеличить числовой массив).

Со списками вы можете использовать команду добавления:

x = [1, 2, 3]
x.append([4, 5])
print (x) #

Этот пример взят из: Разница между добавлением и . расширять методы списка в Python

person U3.1415926    schedule 14.03.2019
comment
Просто примечание: np.append не следует использовать в подобных ситуациях, когда несколько массивов соединяются последовательно, например, см. stackoverflow.com/questions/7133885/ - person user2699; 14.03.2019
comment
np.append — это плохо названная функция покрытия для np.concatenate. В этом случае массивы уже имеют нужное количество измерений: np.concatenate((x,y),axis=1). - person hpaulj; 14.03.2019

np.block поможет вам создать такой массив:

In [109]: B =np.arange(1,5).reshape(2,2)                                        
In [110]: I =np.eye(2).astype(int)                                              
In [111]: Z = np.zeros((2,2),int)                                               
In [112]: np.block?                                                             
In [113]: np.block([[B,I,Z,Z],[I,B,I,Z],[Z,I,B,I],[Z,Z,I,B]])                   
Out[113]: 
array([[1, 2, 1, 0, 0, 0, 0, 0],
       [3, 4, 0, 1, 0, 0, 0, 0],
       [1, 0, 1, 2, 1, 0, 0, 0],
       [0, 1, 3, 4, 0, 1, 0, 0],
       [0, 0, 1, 0, 1, 2, 1, 0],
       [0, 0, 0, 1, 3, 4, 0, 1],
       [0, 0, 0, 0, 1, 0, 1, 2],
       [0, 0, 0, 0, 0, 1, 3, 4]])

block выполняет вложенную последовательность concatenate, начиная с самых внутренних списков. Предыдущие версии использовали hstack во внутренних списках и vstack в этих результатах.

In [118]: np.vstack((np.hstack([B,I,Z,Z]),np.hstack([I,B,I,Z])))                
Out[118]: 
array([[1, 2, 1, 0, 0, 0, 0, 0],
       [3, 4, 0, 1, 0, 0, 0, 0],
       [1, 0, 1, 2, 1, 0, 0, 0],
       [0, 1, 3, 4, 0, 1, 0, 0]])

Списки списков в [113] можно создать с помощью кода, используя нужные размеры, но я не буду вдаваться в эти подробности.

Другой подход заключается в создании целевого массива np.zeros((8,8)) и заполнении нужных блоков. Может быть, даже лучше сделать np.zeros((4,2,4,2)), заполнить его и изменить форму позже.

In [119]: res = np.zeros((4,2,4,2),int)                                         
In [120]: res[np.arange(4),:,np.arange(4),:] = B                                
In [121]: res[np.arange(3),:,np.arange(1,4),:] = I                              
In [122]: res[np.arange(1,4),:,np.arange(3),:] = I  
In [124]: res.reshape(8,8)                                                      
Out[124]: 
array([[1, 2, 1, 0, 0, 0, 0, 0],
       [3, 4, 0, 1, 0, 0, 0, 0],
       [1, 0, 1, 2, 1, 0, 0, 0],
       [0, 1, 3, 4, 0, 1, 0, 0],
       [0, 0, 1, 0, 1, 2, 1, 0],
       [0, 0, 0, 1, 3, 4, 0, 1],
       [0, 0, 0, 0, 1, 0, 1, 2],
       [0, 0, 0, 0, 0, 1, 3, 4]])
person hpaulj    schedule 14.03.2019