pythonarraysnumpymatrixdiagonal

Fill the Diagonal of Each Matrix in a 3D numpy Array with a Vector


Having a 3D numpy array, where each 2D slice represents an individual matrix. I'm looking to replace the diagonal elements of every matrix with a specific set of values.

For instance, if I have a 3x3x3 array:

array([[[a1, a2, a3],
        [a4, a5, a6],
        [a7, a8, a9]],

       [[b1, b2, b3],
        [b4, b5, b6],
        [b7, b8, b9]],

       [[c1, c2, c3],
        [c4, c5, c6],
        [c7, c8, c9]]])

I'd like to replace the diagonals [a1, a5, a9], [b1, b5, b9], and [c1, c5, c9] with a new set of values for each matrix. How can I achieve this?


Solution

  • I would use integer indexing:

    import numpy as np
    
    # Setup:
    arr = np.zeros((3, 4, 6), dtype=int)
    vectors = np.random.randint(1, 9, size=(3, 4))
    
    # Should work for arbitrary `arr` with ndim >= 2
    n = min(arr.shape[-2:])
    idx = np.arange(n)
    
    # Note that `vectors.shape` must broadcast with
    # `(*arr.shape[:-2], n)` for this to work:
    
    arr[..., idx, idx] = vectors