沿 3D NumPy 数组的后 2 个维度移动 window 以获得 3D 块
Moving window along latter 2 dimensions of a 3D NumPy array to obtain 3D chunks
我有一个形状为 (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]]])
我想使用沿后两个维度移动 window 来获得形状 2 × 3 × 3
的 3D 块(在本例中为 9 × 9
)。第一维的大小(我称之为“深度”)是任意的。第一个块的示例是:
>>> 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
应用到我的案例中,如 and played around with fancy indexing as in #15722324,但没有达到预期的结果。
谢谢!
您可以为此使用 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.]]],
...
我有一个形状为 (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]]])
我想使用沿后两个维度移动 window 来获得形状 2 × 3 × 3
的 3D 块(在本例中为 9 × 9
)。第一维的大小(我称之为“深度”)是任意的。第一个块的示例是:
>>> 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
应用到我的案例中,如
谢谢!
您可以为此使用 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.]]],
...