Copy flat list of upper triangle entries to full matrix?

前端 未结 4 1331
礼貌的吻别
礼貌的吻别 2021-01-21 13:53

I have the upper triangle entries (including diagonal) of a symmetric matrix in a flat list (concatenated rows), and I want to use them to fill in the full matrix, including the

4条回答
  •  暖寄归人
    2021-01-21 14:21

    Inspired by this solution, you can use boolean indexing to set elements and as such might be pretty efficient. Here's one way to implement it -

    def mask_based_utri2mat(utri,ntotal):
        # Setup output array
        out = np.empty((ntotal,ntotal))
    
        # Create upper triang. mask
        mask = np.triu(np.ones((ntotal,ntotal),dtype=bool))
    
        # Set upper triang. elements with mask
        out[mask] = utri
    
        # Set lower triang. elements with transposed mask
        out.T[mask] = utri
        return out    
    

    Runtime tests -

    In [52]: # Inputs
        ...: ntotal = 100
        ...: utri = np.random.rand(np.triu_indices(ntotal)[0].size)
        ...: 
    
    In [53]: np.allclose(mask_based_utri2mat(utri,ntotal),utri2mat(utri,ntotal))
    Out[53]: True
    
    In [54]: %timeit utri2mat(utri,ntotal)
    1000 loops, best of 3: 270 µs per loop
    
    In [55]: %timeit mask_based_utri2mat(utri,ntotal)
    10000 loops, best of 3: 127 µs per loop
    
    In [56]: # Inputs
        ...: ntotal = 1000
        ...: utri = np.random.rand(np.triu_indices(ntotal)[0].size)
        ...: 
    
    In [57]: np.allclose(mask_based_utri2mat(utri,ntotal),utri2mat(utri,ntotal))
    Out[57]: True
    
    In [58]: %timeit utri2mat(utri,ntotal)
    10 loops, best of 3: 53.9 ms per loop
    
    In [59]: %timeit mask_based_utri2mat(utri,ntotal)
    100 loops, best of 3: 15.1 ms per loop
    

提交回复
热议问题