Generating banded matrices using numpy

前端 未结 3 2082
梦毁少年i
梦毁少年i 2021-01-06 14:17

I\'m using the following piece of code to create a banded matrix from a generator g:

def banded(g, N):
    \"\"\"Creates a `g` generated banded          


        
3条回答
  •  遥遥无期
    2021-01-06 14:47

    Here's one with np.lib.stride_tricks.as_strided to give us a 2D view into a zeros padded 1D version of the input and as such pretty memory efficient and hence performant too. This trick had been explored numerous times - 1,2.

    Thus, the implementation would be -

    def sliding_windows(a, W):
        a = np.asarray(a)
        p = np.zeros(W-1,dtype=a.dtype)
        b = np.concatenate((p,a,p))
        s = b.strides[0]
        strided = np.lib.stride_tricks.as_strided
        return strided(b[W-1:], shape=(W,len(a)+W-1), strides=(-s,s))
    

    Sample runs -

    In [99]: a = [1,2,3]
    
    In [100]: sliding_windows(a, W=3)
    Out[100]: 
    array([[1, 2, 3, 0, 0],
           [0, 1, 2, 3, 0],
           [0, 0, 1, 2, 3]])
    
    In [101]: a = [1,2,3,4,5]
    
    In [102]: sliding_windows(a, W=3)
    Out[102]: 
    array([[1, 2, 3, 4, 5, 0, 0],
           [0, 1, 2, 3, 4, 5, 0],
           [0, 0, 1, 2, 3, 4, 5]])
    

    With the same philosophy, but less messier version, we can also leverage np.lib.stride_tricks.as_strided based scikit-image's view_as_windows to get sliding windows. More info on use of as_strided based view_as_windows.

    from skimage.util.shape import view_as_windows
    
    def sliding_windows_vw(a, W):
        a = np.asarray(a)
        p = np.zeros(W-1,dtype=a.dtype)
        b = np.concatenate((p,a,p))
        return view_as_windows(b,len(a)+W-1)[::-1]
    

提交回复
热议问题