pythonnumpymatrix

How to get triangle upper matrix without the diagonal using numpy


Lets say I have the following matrix:

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

How can I extract the upper triangle matrix without the diagonal efficiently? The output would be the following array:

B = np.array([2,3,6])

Solution

  • One approach with masking -

    def upper_tri_masking(A):
        m = A.shape[0]
        r = np.arange(m)
        mask = r[:,None] < r
        return A[mask]
    

    Another with np.triu_indices -

    def upper_tri_indexing(A):
        m = A.shape[0]
        r,c = np.triu_indices(m,1)
        return A[r,c]
    

    Sample run -

    In [403]: A
    Out[403]: 
    array([[79, 17, 79, 58, 14],
           [87, 63, 89, 26, 31],
           [69, 34, 90, 24, 96],
           [59, 60, 80, 52, 46],
           [75, 80, 11, 61, 47]])
    
    In [404]: upper_tri_masking(A)
    Out[404]: array([17, 79, 58, 14, 89, 26, 31, 24, 96, 46])
    

    Runtime test -

    In [415]: A = np.random.randint(0,9,(5000,5000))
    
    In [416]: %timeit upper_tri_masking(A)
    10 loops, best of 3: 64.2 ms per loop
    
    In [417]: %timeit upper_tri_indexing(A)
    1 loop, best of 3: 252 ms per loop