为 numpy ndarray 移动子数组查找最大值及其索引的 pythonic 方法是什么?
What is a pythonic way of finding maximum values and their indices for moving subarrays for numpy ndarray?
我有 3 维或 4 维的 numpy ndarray。我想在具有指定步幅的移动子数组 window 中找到最大值及其索引。
例如,假设我有一个 4x4 的二维数组,为了简单起见,我的移动子数组 window 是 2x2,步幅为 2:
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12],
[13,14,15,16]].
我想找
[[ 6 8],
[14 16]]
最大值和
[(1,1), (3,1),
(3,1), (3,3)]
用于索引作为输出。
是否有不使用循环的 ndarray 的简洁、高效的实现?
这是一个使用 stride_tricks
的解决方案:
def make_panes(arr, window):
arr = np.asarray(arr)
r,c = arr.shape
s_r, s_c = arr.strides
w_r, w_c = window
if c % w_c != 0 or r % w_r != 0:
raise ValueError("Window doesn't fit array.")
shape = (r / w_r, c / w_c, w_r, w_c)
strides = (w_r*s_r, w_c*s_c, s_r, s_c)
return np.lib.stride_tricks.as_strided(arr, shape, strides)
def max_in_panes(arr, window):
w_r, w_c = window
r, c = arr.shape
panes = make_panes(arr, window)
v = panes.reshape((-1, w_r * w_c))
ix = np.argmax(v, axis=1)
max_vals = v[np.arange(r/w_r * c/w_c), ix]
i = np.repeat(np.arange(0,r,w_r), c/w_c)
j = np.tile(np.arange(0, c, w_c), r/w_r)
rel_i, rel_j = np.unravel_index(ix, window)
max_ix = i + rel_i, j + rel_j
return max_vals, max_ix
演示:
>>> vals, ix = max_in_panes(x, (2,2))
>>> print vals
[[ 6 8]
[14 16]]
>>> print ix
(array([1, 1, 3, 3]), array([1, 3, 1, 3]))
请注意,这是未经测试的,旨在与二维数组一起使用。我将把 n-d 数组的概括留给 reader...
我有 3 维或 4 维的 numpy ndarray。我想在具有指定步幅的移动子数组 window 中找到最大值及其索引。
例如,假设我有一个 4x4 的二维数组,为了简单起见,我的移动子数组 window 是 2x2,步幅为 2:
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12],
[13,14,15,16]].
我想找
[[ 6 8],
[14 16]]
最大值和
[(1,1), (3,1),
(3,1), (3,3)]
用于索引作为输出。
是否有不使用循环的 ndarray 的简洁、高效的实现?
这是一个使用 stride_tricks
的解决方案:
def make_panes(arr, window):
arr = np.asarray(arr)
r,c = arr.shape
s_r, s_c = arr.strides
w_r, w_c = window
if c % w_c != 0 or r % w_r != 0:
raise ValueError("Window doesn't fit array.")
shape = (r / w_r, c / w_c, w_r, w_c)
strides = (w_r*s_r, w_c*s_c, s_r, s_c)
return np.lib.stride_tricks.as_strided(arr, shape, strides)
def max_in_panes(arr, window):
w_r, w_c = window
r, c = arr.shape
panes = make_panes(arr, window)
v = panes.reshape((-1, w_r * w_c))
ix = np.argmax(v, axis=1)
max_vals = v[np.arange(r/w_r * c/w_c), ix]
i = np.repeat(np.arange(0,r,w_r), c/w_c)
j = np.tile(np.arange(0, c, w_c), r/w_r)
rel_i, rel_j = np.unravel_index(ix, window)
max_ix = i + rel_i, j + rel_j
return max_vals, max_ix
演示:
>>> vals, ix = max_in_panes(x, (2,2))
>>> print vals
[[ 6 8]
[14 16]]
>>> print ix
(array([1, 1, 3, 3]), array([1, 3, 1, 3]))
请注意,这是未经测试的,旨在与二维数组一起使用。我将把 n-d 数组的概括留给 reader...