在多维数组中设置滑动 windows 作为列(来自 MATLAB 的 IM2COL)- Python
Setup sliding windows as columns (IM2COL from MATLAB) in multi-dimensional array - Python
目前,我有一个 4d 数组,比方说,
arr = np.arange(48).reshape((2,2,3,4))
我想应用一个函数,该函数将二维数组作为从 arr
切片的每个二维数组的输入。我已经搜索并阅读了this question,这正是我想要的
我使用的函数是 im2col_sliding_broadcasting()
,它是从 得到的。它需要一个二维数组和 2 个元素的列表作为输入,returns 一个二维数组。在我的例子中:它需要 3x4
二维数组和一个列表 [2, 2]
和 returns 4x6
二维数组。
我考虑过使用 apply_along_axis()
但 as said 它只接受 1d
函数作为参数。我不能这样应用 im2col
函数。
我想要一个形状为 2x2x4x6
的输出。当然我可以用for循环实现这个,但是我听说它太费时间了:
import numpy as np
def im2col_sliding_broadcasting(A, BSZ, stepsize=1):
# source:
# Parameters
M, N = A.shape
col_extent = N - BSZ[1] + 1
row_extent = M - BSZ[0] + 1
# Get Starting block indices
start_idx = np.arange(BSZ[0])[:, None]*N + np.arange(BSZ[1])
# Get offsetted indices across the height and width of input array
offset_idx = np.arange(row_extent)[:, None]*N + np.arange(col_extent)
# Get all actual indices & index into input array for final output
return np.take(A, start_idx.ravel()[:, None] + offset_idx.ravel()[::stepsize])
arr = np.arange(48).reshape((2,2,3,4))
output = np.empty([2,2,4,6])
for i in range(2):
for j in range(2):
temp = im2col_sliding_broadcasting(arr[i, j], [2,2])
output[i, j] = temp
因为我的 arr
实际上是一个 10000x3x64x64
数组。所以我的问题是:还有另一种方法可以更有效地做到这一点吗?
我们可以利用 np.lib.stride_tricks.as_strided
based scikit-image's view_as_windows
to get sliding windows. .
from skimage.util.shape import view_as_windows
W1,W2 = 2,2 # window size
# create sliding windows along last two axes1
w = view_as_windows(arr,(1,1,W1,W2))[...,0,0,:,:]
# Merge the window axes (tha last two axes) and
# merge the axes along which those windows were created (3rd and 4th axes)
outshp = arr.shape[:-2] + (W1*W2,) + ((arr.shape[-2]-W1+1)*(arr.shape[-1]-W2+1),)
out = w.transpose(0,1,4,5,2,3).reshape(outshp)
最后一步强制复制。所以,如果可能的话,跳过它。
目前,我有一个 4d 数组,比方说,
arr = np.arange(48).reshape((2,2,3,4))
我想应用一个函数,该函数将二维数组作为从 arr
切片的每个二维数组的输入。我已经搜索并阅读了this question,这正是我想要的
我使用的函数是 im2col_sliding_broadcasting()
,它是从 3x4
二维数组和一个列表 [2, 2]
和 returns 4x6
二维数组。
我考虑过使用 apply_along_axis()
但 as said 它只接受 1d
函数作为参数。我不能这样应用 im2col
函数。
我想要一个形状为 2x2x4x6
的输出。当然我可以用for循环实现这个,但是我听说它太费时间了:
import numpy as np
def im2col_sliding_broadcasting(A, BSZ, stepsize=1):
# source:
# Parameters
M, N = A.shape
col_extent = N - BSZ[1] + 1
row_extent = M - BSZ[0] + 1
# Get Starting block indices
start_idx = np.arange(BSZ[0])[:, None]*N + np.arange(BSZ[1])
# Get offsetted indices across the height and width of input array
offset_idx = np.arange(row_extent)[:, None]*N + np.arange(col_extent)
# Get all actual indices & index into input array for final output
return np.take(A, start_idx.ravel()[:, None] + offset_idx.ravel()[::stepsize])
arr = np.arange(48).reshape((2,2,3,4))
output = np.empty([2,2,4,6])
for i in range(2):
for j in range(2):
temp = im2col_sliding_broadcasting(arr[i, j], [2,2])
output[i, j] = temp
因为我的 arr
实际上是一个 10000x3x64x64
数组。所以我的问题是:还有另一种方法可以更有效地做到这一点吗?
我们可以利用 np.lib.stride_tricks.as_strided
based scikit-image's view_as_windows
to get sliding windows.
from skimage.util.shape import view_as_windows
W1,W2 = 2,2 # window size
# create sliding windows along last two axes1
w = view_as_windows(arr,(1,1,W1,W2))[...,0,0,:,:]
# Merge the window axes (tha last two axes) and
# merge the axes along which those windows were created (3rd and 4th axes)
outshp = arr.shape[:-2] + (W1*W2,) + ((arr.shape[-2]-W1+1)*(arr.shape[-1]-W2+1),)
out = w.transpose(0,1,4,5,2,3).reshape(outshp)
最后一步强制复制。所以,如果可能的话,跳过它。