2017-02-10 10 views
8
import numpy as np 

A = np.array([[1, 2], 
       [3, 4]])  
B = np.array([[5, 6], 
       [7, 8]]) 

C = np.array([[1, 2, 0, 0], 
       [3, 4, 0, 0], 
       [0, 0, 5, 6], 
       [0, 0, 7, 8]]) 

chciałbym zrobić C bezpośrednio od A i B, czy są jakieś sposoby, po prostu skonstruować przekątnej tablicy C? Dzięki.python numpy: jak zbudować dużą przekątną macierzy (matrix) z dwóch małych tablicy

+0

jest 'C' żądane wyjście czy co? – marmeladze

+0

Tak, C jest żądanym wyjściem. – ollydbg23

Odpowiedz

7

Podejście nr 1: Prostym sposobem byłoby z np.bmat -

Z = np.zeros((2,2),dtype=int) # Create off-diagonal zeros array 
out = np.asarray(np.bmat([[A, Z], [Z, B]])) 

run Sample -

In [24]: Z = np.zeros((2,2),dtype=int) 

In [25]: np.asarray(np.bmat([[A, Z], [Z, B]])) 
Out[25]: 
array([[1, 2, 0, 0], 
     [3, 4, 0, 0], 
     [0, 0, 5, 6], 
     [0, 0, 7, 8]]) 

Podejście nr 2: dla numeru generycznego tablic, możemy użyć masking -

def diag_block_mat_boolindex(L): 
    shp = L[0].shape 
    mask = np.kron(np.eye(len(L)), np.ones(shp))==1 
    out = np.zeros(np.asarray(shp)*len(L),dtype=int) 
    out[mask] = np.concatenate(L).ravel() 
    return out 

Podejście nr 3: dla numeru generycznego tablic, inny sposób z multi-dimensional slicing -

def diag_block_mat_slicing(L): 
    shp = L[0].shape 
    N = len(L) 
    r = range(N) 
    out = np.zeros((N,shp[0],N,shp[1]),dtype=int) 
    out[r,:,r,:] = L 
    return out.reshape(np.asarray(shp)*N) 

Przykładowe przebiegi -

In [137]: A = np.array([[1, 2], 
    ...:    [3, 4]])  
    ...: B = np.array([[5, 6], 
    ...:    [7, 8]]) 
    ...: C = np.array([[11, 12], 
    ...:    [13, 14]]) 
    ...: D = np.array([[15, 16], 
    ...:    [17, 18]]) 
    ...: 

In [138]: diag_block_mat_boolindex((A,B,C,D)) 
Out[138]: 
array([[ 1, 2, 0, 0, 0, 0, 0, 0], 
     [ 3, 4, 0, 0, 0, 0, 0, 0], 
     [ 0, 0, 5, 6, 0, 0, 0, 0], 
     [ 0, 0, 7, 8, 0, 0, 0, 0], 
     [ 0, 0, 0, 0, 11, 12, 0, 0], 
     [ 0, 0, 0, 0, 13, 14, 0, 0], 
     [ 0, 0, 0, 0, 0, 0, 15, 16], 
     [ 0, 0, 0, 0, 0, 0, 17, 18]]) 

In [139]: diag_block_mat_slicing((A,B,C,D)) 
Out[139]: 
array([[ 1, 2, 0, 0, 0, 0, 0, 0], 
     [ 3, 4, 0, 0, 0, 0, 0, 0], 
     [ 0, 0, 5, 6, 0, 0, 0, 0], 
     [ 0, 0, 7, 8, 0, 0, 0, 0], 
     [ 0, 0, 0, 0, 11, 12, 0, 0], 
     [ 0, 0, 0, 0, 13, 14, 0, 0], 
     [ 0, 0, 0, 0, 0, 0, 15, 16], 
     [ 0, 0, 0, 0, 0, 0, 17, 18]]) 
+0

Czy możesz uczynić go bardziej programowym dla 10 tablic takich jak A-J? – MYGz

+0

@Divakar, czy można przekonwertować z powrotem na 'np.array'? Wygląda teraz na 'np.matrrix'. – ollydbg23

+0

@ ollydbg23 Edytowane dla tego. – Divakar

Powiązane problemy