2

I'd like to ask how can I efficiently generate a numpy 3D array from a 2D array with each row filling the diagonal part of the new array? For example, the input 2D array is

array([[1, 2],
       [3, 4],
       [5, 6],
       [7, 8]])

and I want the output to be

array([[[1, 0],
        [0, 2]],

       [[3, 0],
        [0, 4]],

       [[5, 0],
        [0, 6]],

       [[7, 0],
        [0, 8]]])

Typically, the size of the first dimensional is very large. Thanks in advance.

4
  • How are you currently generating, and why don't you consider it efficient enough? Commented Jan 24, 2023 at 13:14
  • I used a for-loop to diag each row, but this is low efficient since normally the input array contains thousands of rows Commented Jan 24, 2023 at 13:21
  • np.einsum('jk,kl->jkl', arr, np.eye(2, dtype=int)) or arr[...,None] * np.eye(2, dtype=int)[None] Commented Jan 24, 2023 at 13:28
  • @MichaelSzczesny Thanks so much for your reply. It works nicely with the einsum :) Commented Jan 24, 2023 at 13:50

2 Answers 2

1

Assuming a the input and using indexing with unravel_index:

x, y = np.unravel_index(np.arange(a.size), a.shape)

out = np.zeros(a.shape+(a.shape[-1],), dtype=a.dtype)

out[x, y, y] = a.flat

Output:

array([[[1, 0],
        [0, 2]],

       [[3, 0],
        [0, 4]],

       [[5, 0],
        [0, 6]],

       [[7, 0],
        [0, 8]]])

timings:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.