nickos556
nickos556

Reputation: 347

Stack numpy array onto diagonal

Given N 2d numpy arrays, is there a neat way in which I can 'stack' or 'bolt' them together on the diagonal, filling any new slots with 0? E.g. given:

arr1 = np.array([[1, 2],
                 [3, 4]])

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

I want to create:

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

Upvotes: 3

Views: 331

Answers (4)

hpaulj
hpaulj

Reputation: 231385

np has a relatively new block function that concatenates nested lists of arrays. But it requires specifying the zero fill blocks:

In [15]: np.block([[arr1, np.zeros((2,3),int)], [np.zeros((3,2),int), arr2]])
Out[15]: 
array([[1, 2, 0, 0, 0],
       [3, 4, 0, 0, 0],
       [0, 0, 9, 8, 7],
       [0, 0, 6, 5, 4],
       [0, 0, 3, 2, 1]])

Upvotes: 1

nickos556
nickos556

Reputation: 347

I just found this which seems to do exactly what I need:

https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.block_diag.html

>> from scipy.linalg import block_diag
>>> A = [[1, 0],
...      [0, 1]]
>>> B = [[3, 4, 5],
...      [6, 7, 8]]
>>> C = [[7]]
>>> block_diag(A, B, C)
[[1 0 0 0 0 0]
 [0 1 0 0 0 0]
 [0 0 3 4 5 0]
 [0 0 6 7 8 0]
 [0 0 0 0 0 7]]

Upvotes: 1

user2357112
user2357112

Reputation: 281177

There's a function for that.

scipy.linalg.block_diag(arr1, arr2)

It takes arbitrarily many parameters:

scipy.linalg.block_diag(*list_of_arrays)

Upvotes: 5

John1024
John1024

Reputation: 113864

Try:

>>> arr = np.zeros((5, 5))
>>> arr[:2, :2] = arr1
>>> arr[2:, 2:] = arr2

And, to verify that it worked, we can display arr:

>>> arr
array([[ 1.,  2.,  0.,  0.,  0.],
       [ 3.,  4.,  0.,  0.,  0.],
       [ 0.,  0.,  9.,  8.,  7.],
       [ 0.,  0.,  6.,  5.,  4.],
       [ 0.,  0.,  3.,  2.,  1.]])

Upvotes: 3

Related Questions