【问题标题】:Python split array into intersecting subarraysPython将数组拆分为相交的子数组
【发布时间】:2020-09-01 12:48:16
【问题描述】:

我想将一个数组拆分为等长的相交子数组(前一个数组的最后一个元素与下一个数组的第一个元素重合,并且具有周期性边界条件)。

例如

myarray = np.arange(18)

输出:

splitarray = [[0,1,2,3,4],[4,5,6,7,8],[8,9,10,11,12],[12,13,14,15,16],[16,17,0,1,2]]

(最后一个子数组的最后3个元素对应初始数组的前3个元素!)

在 Python 中实现这一点最有效的方法是什么?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    ski.util.view_as_windows 的纯 numpy 等效项是 np.lib.stride_tricks.as_strided

    arr = np.arange(18)
    w = 5
    
    if arr.size == 1:
        h = 1
        x = 4
    else:
        h = np.ceil((arr.size - 1) / (w - 1)).astype(int)
        x = (1 - arr.size) % (w - 1)
    
    view = np.lib.stride_tricks.as_strided(np.r_[arr, arr[:x]], shape=(h, w), strides=((w - 1) * arr.strides[0], arr.strides[0]))
    

    结果是:

    >>> view
    array([[ 0,  1,  2,  3,  4],
           [ 4,  5,  6,  7,  8],
           [ 8,  9, 10, 11, 12],
           [12, 13, 14, 15, 16],
           [16, 17,  0,  1,  2]])
    

    重叠的元素实际上是指同一个内存,所以使用这个视图要非常小心。

    【讨论】:

      【解决方案2】:

      您可以使用 skimage 的 view_as_windows 获取输入数组的重叠视图,并为最后一个窗口相应地连接第一个 w-1 项:

      from skimage.util import view_as_windows
      
      def view_strided_with_roll(a, w):
          a = np.r_[a, a[:w-1]]
          return view_as_windows(a, window_shape=w, step=w-1)
      

      myarray = np.arange(18) 
      view_strided_with_roll(myarray, 5)
      array([[ 0,  1,  2,  3,  4],
             [ 4,  5,  6,  7,  8],
             [ 8,  9, 10, 11, 12],
             [12, 13, 14, 15, 16],
             [16, 17,  0,  1,  2]])
      

      【讨论】:

      • 如果你只想使用numpy:np.array([np.roll(myarray, len(myarray) - i)[:5] for i in range(0,len(myarray),4)])
      • 虽然没有矢量化,但对于较大的数组不会很好地扩展@MBeale
      • @MBeale。我已经发布了正确的 numpy 解决方案
      猜你喜欢
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2020-09-13
      相关资源
      最近更新 更多