Creating a 3-D (or larger) diagonal NumPy array from diagonals

Viewed 76

Is there an efficient 'Numpy'-based solution to create a 3 (or higher) dimensional diagonal matrix?

More specifically, I am looking for a shorter (and perhaps more efficient) solution to replace the following:

N = 100
M = 4
d = np.random.randn(N)   # calculated in the real use case from other parameters
A = np.zeros(M, M, N, dtype=d.dtype)
for i in range(M):
    A[i, i, :] = d

The above-mentioned solution will be slow if M is large, and I think not very memory-efficient as d is copied M times in the memory.

1 Answers

Here's one with np.einsum diag-view -

np.einsum('iij->ij',A)[:] =  d

Looking at the string notation, this also translates well from the iterative part : A[i, i, :] = d.

Generalize to ndarray with ellipsis -

np.einsum('ii...->i...',A)[:] =  d
Related