【问题标题】:Moving window along latter 2 dimensions of a 3D NumPy array to obtain 3D chunks沿着 3D NumPy 数组的后 2 个维度移动窗口以获得 3D 块
【发布时间】:2020-11-11 18:20:05
【问题描述】:

我有一个形状为 (2, 9, 9) 的 3D NumPy 数组 a,如下所示:

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

       [[4, 2, 0, 1, 6, 7, 1, 0, 8],
        [1, 5, 3, 6, 4, 2, 4, 8, 3],
        [7, 4, 9, 9, 1, 9, 7, 3, 1],
        [3, 6, 1, 2, 5, 4, 1, 3, 0],
        [3, 3, 6, 6, 9, 8, 4, 2, 8],
        [7, 9, 1, 3, 0, 2, 0, 7, 4],
        [6, 7, 9, 3, 0, 2, 1, 9, 2],
        [1, 0, 3, 4, 7, 8, 1, 6, 5],
        [4, 4, 7, 8, 3, 7, 0, 4, 7]]])

我想使用沿后两个维度(在本例中为 9 × 9)的移动窗口来获得形状为 2 × 3 × 3 的 3D 块。第一个维度的大小(我称之为“深度”)是任意的。第一个块的示例是:

>>> array([
       [[np.nan, np.nan, np.nan],
        [np.nan, 4, 5],
        [np.nan, 9, 2]],

        [[np.nan, np.nan, np.nan],
        [np.nan, 4, 2],
        [np.nan, 1, 5]]])

第二个是:

>>> array([
       [[np.nan, np.nan, np.nan],
        [4, 5, 1],
        [9, 2, 2]],

        [[np.nan, np.nan, np.nan],
        [4, 2, 0],
        [1, 5, 3]]])

等等……

我稍后需要对这些块应用更复杂的函数,而不是简单的平均值或类似的函数,所以我会很欣赏它们的新数组(我想这会占用大量内存,是否有不同的方法?可能矢量化?不过没必要)

我尝试将np.lib.stride_tricks.as_strided 应用到我的案例中,就像#44305987 中一样,并尝试了像#15722324 中那样的精美索引,但没有达到预期的结果。

谢谢!

【问题讨论】:

  • 我发布了一个类似here 的通用解决方案 - 你只需要事先使用 NaN 来pad

标签: python arrays numpy convolution


【解决方案1】:

您可以为此使用skimage.util.view_as_windows。由于您似乎希望这些窗口视图的最小大小为 2 元素,因此您可以将数组分配给更大的 np.nan 数组,并获取结果数组的跨步视图:

from skimage.util import view_as_windows

i,j,k= a.shape
a_exp = np.full((i,j+2,k+2), np.nan)
a_exp[:,1:j+1,1:k+1] = a

或者你也可以对np.pad做同样的事情:

a_exp = np.pad(a.astype('float'), 
               pad_width=((0,0),(1,1),(1,1)), 
               constant_values=np.nan)

并查看跨步:

out = view_as_windows(a_exp, (a.shape[0],3,3))

out
array([[[[[[nan, nan, nan],
           [nan,  4.,  5.],
           [nan,  9.,  2.]],

          [[nan, nan, nan],
           [nan,  4.,  2.],
           [nan,  1.,  5.]]],


         [[[nan, nan, nan],
           [ 4.,  5.,  1.],
           [ 9.,  2.,  2.]],

          [[nan, nan, nan],
           [ 4.,  2.,  0.],
           [ 1.,  5.,  3.]]],
         ...

【讨论】:

  • 感谢skimage.util.view_as_windows,非常有用!我一直在 scikit 周围游弋,但从未接触过这种方法。
  • 不可知论者,使用view_as_windows(a_exp, (1,3,3))[...,0,:,:],如果OP需要第一、第二块顺序,则可能使用transpose(1,2,0,3,4)[0,1]。更多信息 - stackoverflow.com/a/51890064
  • @Divakar 我会看看,谢谢。我只是感兴趣,你认为你可以指出一个 NumPy 解决问题的方法吗?据我所知,np.convolve 仅对一维数组进行排序...
  • @janchytry 卷积用于求和。你在总结那些窗户吗?如果您想求和,您可能需要多维卷积 - docs.scipy.org/doc/scipy/reference/generated/…
  • @Divakar 不,我没有,这可能是我简单地移动窗口与卷积核的不当行为。我以后要应用的功能是内核无法表达的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-10
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 2017-01-18
  • 1970-01-01
相关资源
最近更新 更多