Search code examples
numpysumaxisshapesdiagonal

How to choose 2D diagonals of a 3D NumPy array


I define an array as :

XRN =np.array([[[0,1,0,1,0,1,0,1,0,1],
    [0,1,1,0,0,1,0,1,0,1],
    [0,1,0,0,1,1,0,1,0,1],
    [0,1,0,1,0,0,1,1,0,1],],
    [[0,1,0,1,0,1,1,0,0,1],
    [0,1,0,1,0,1,0,1,1,0],
    [1,1,1,0,0,0,0,1,0,1],
    [0,1,0,1,0,0,1,1,0,1],],
    [[0,1,0,1,0,1,1,1,0,0],
    [0,1,0,1,1,1,0,1,0,0],
    [0,1,0,1,1,0,0,1,0,1],
    [0,1,0,1,0,0,1,1,0,1],]])
print(XRN.shape,XRN)
XRN_LEN = XRN.shape[1]

I can obtain the sum of inner matrix with :

    XRN_UP = XRN.sum(axis=1)
    print("XRN_UP",XRN_UP.shape,XRN_UP)

XRN_UP (3, 10) [[0 4 1 2 1 3 1 4 0 4]
 [1 4 1 3 0 2 2 3 1 3]
 [0 4 0 4 2 2 2 4 0 2]]

I want to get the sum of all diagonals with the same shape (3,10)

I tested the code :

  RIGHT = [XRN.diagonal(i,axis1=0,axis2=1).sum(axis=1) for i in range(XRN_LEN)]
  np_RIGHT = np.array(RIGHT)
  print("np_RIGHT=",np_RIGHT.shape,np_RIGHT)

but got

np_RIGHT= (4, 10) [[0 3 0 3 1 2 0 3 1 2]
 [1 3 2 1 0 1 1 3 0 3]
 [0 2 0 1 1 1 1 2 0 2]
 [0 1 0 1 0 0 1 1 0 1]]

I checked all values for axis1 and axis 2 but never got the shape(3,10) : How can I do ?

axis1   axis2   shape
0       1       (4,10)
0       2       (4,4)
1       0       (4,10)
1       2       (4,3)
2       0       (4,4)
2       1       (4,3)

Solution

  • If I understand correctly, you want to sum all possible diagonals on the three elements separately. If that's the case, then you must apply np.diagonal on axis1=1 and axis2=2. This way, you end up with 10 diagonals per element which you sum down to 10 values per element. There are 3 elements, so the resulting shape is (10, 3):

    >>> np.array([XRN.diagonal(i, 1, 2).sum(1) for i in range(XRN.shape[-1])])
    array([[2, 3, 2],
           [2, 1, 2],
           [1, 1, 2],
           [3, 2, 3],
           [2, 2, 2],
           [2, 2, 2],
           [2, 3, 3],
           [2, 2, 2],
           [1, 0, 0],
           [1, 1, 0]])