Make special diagonal matrix in Numpy

前端 未结 5 1328
时光取名叫无心
时光取名叫无心 2020-12-06 01:09

I am trying to make a numpy array that looks like this:

[a b c       ]
[  a b c     ]
[    a b c   ]
[      a b c ] 

So this involves updat

5条回答
  •  臣服心动
    2020-12-06 01:46

    import numpy as np
    
    def using_tile_and_stride():
        arr = np.tile(np.array([10,20,30,0,0,0], dtype='float'), (4,1))
        row_stride, col_stride = arr.strides
        arr.strides = row_stride-col_stride, col_stride
        return arr
    
    In [108]: using_tile_and_stride()
    Out[108]: 
    array([[ 10.,  20.,  30.,   0.,   0.,   0.],
           [  0.,  10.,  20.,  30.,   0.,   0.],
           [  0.,   0.,  10.,  20.,  30.,   0.],
           [  0.,   0.,   0.,  10.,  20.,  30.]])
    

    Other, slower alternatives include:

    import numpy as np
    
    import numpy.lib.stride_tricks as stride
    
    def using_put():
        arr = np.zeros((4,6), dtype='float')
        a, b, c = 10, 20, 30
        nrows, ncols = arr.shape
        ind = (np.arange(3) + np.arange(0,(ncols+1)*nrows,ncols+1)[:,np.newaxis]).ravel()
        arr.put(ind, [a, b, c])
        return arr
    
    def using_strides():
        return np.flipud(stride.as_strided(
            np.array([0, 0, 0, 10, 20, 30, 0, 0, 0], dtype='float'), 
            shape=(4, 6), strides = (8, 8)))
    

    If you use using_tile_and_stride, note that the array is only appropriate for read-only purposes. Otherwise, if you were to try to modify the array, you might be surprised when multiple array locations change simultaneously:

    In [32]: arr = using_tile_and_stride()
    
    In [33]: arr[0, -1] = 100
    
    In [34]: arr
    Out[34]: 
    array([[  10.,   20.,   30.,    0.,  100.],
           [ 100.,   10.,   20.,   30.,    0.],
           [   0.,    0.,   10.,   20.,   30.],
           [  30.,    0.,    0.,   10.,   20.]])
    

    You could work around this by returning np.ascontiguousarray(arr) instead of just arr, but then using_tile_and_stride would be slower than using_put. So if you intend to modify the array, using_put would be a better choice.

提交回复
热议问题