我已经成功地找到了每个滑动窗口视图中使用NumPy中的amax
和sliding_window_view
函数的最大值,如下所示:
import numpy as np
a = np.random.randint(0, 100, (5, 6)) # 2D array
array([[51, 92, 14, 71, 60, 20],
[82, 86, 74, 74, 87, 66],
[23, 2, 21, 52, 1, 87],
[29, 37, 1, 63, 59, 20],
[32, 75, 57, 21, 83, 48]])
windows = np.lib.stride_tricks.sliding_window_view(a, (3, 3))
np.amax(windows, axis=(2, 3))
array([[92, 92, 87, 87],
[86, 86, 87, 87],
[75, 75, 83, 87]])
现在,我正试图找到考虑窗口的原始数组中最大值的位置。
预期输出
The first element i.e. `92` should give position `(1, 0)`.
The second element i.e. `92` should give position `(1, 0)`.
The third element i.e. `87` should give position `(4, 1)`.
.
.
The seventh element i.e. `87` should give position `(4, 1)`.
The twelveth element i.e. `87` should give position `(5, 2)`.
.
so on
注:每个值只需要一个位置。因此,如果一个窗口内有多个位置,则只返回第一个位置。
此解决方案为每个窗口提供索引,但如果最大值在某个窗口中出现两次,则不提供唯一索引:
maxvals = np.amax(windows, axis=(2, 3))
# array([[92, 92, 87, 87],
# [86, 86, 87, 87],
# [75, 75, 83, 87]])
indx = np.array((windows == np.expand_dims(maxvals, axis = (2, 3)).nonzero())
,它为windows
数组中的四个轴中的每个轴返回一个数组。现在,我们对每个窗口中的相对索引位置进行一些数学运算,以获得原始数组中出现最大值的索引:
np.sum(indx.reshape(2, 2, -1), axis = 0)
# array([[0, 0, 1, 1, 2, 1, 1, 1, 1, 2, 4, 4, 4, 2],
# [1, 1, 4, 4, 5, 1, 1, 4, 4, 5, 1, 1, 4, 5]])
进行重塑是为了方便添加索引。前两个数组给出了窗口位置。第二个两个数组是相对于窗口的位置。所以我们把它们加起来。您可以检查沿第二个轴的每一对值是否是您需要的一对索引。
如果没有循环,则可以使用另一个SO post:
unique_values, index = np.unique(a, return_index=True)
result = index[np.searchsorted(unique_values, np.amax(windows, axis=(2, 3)))]
ind = np.dstack((result % a.shape[1], result // a.shape[1]))
ind.reshape(12, 2)
# [[1 0]
# [1 0]
# [4 1]
# [5 1]
# [1 1]
# [1 1]
# [4 1]
# [5 1]
# [1 4]
# [1 4]
# [4 4]
# [4 4]]
如果其他人想要有一个滑动的,非重叠的窗口,我做了一些修改,以使所选的答案工作:
-
调整滑动窗口调用做
windows = np.lib.stride_tricks.sliding_window_view(arr, (row_window, col_window))[ ::row_window, ::col_window ]
-
如果你从
跳过窗口,sliding_window_view
sum
在最后获得绝对位置不起作用
这是我得到的
def get_max_idxs(arr, row_window, col_window):
"""Get the indices of the maximum value in each window."""
windows = np.lib.stride_tricks.sliding_window_view(arr, (row_window, col_window))[
::row_window, ::col_window
]
maxvals = np.nanmax(windows, axis=(2, 3))
indx = np.array((windows == np.expand_dims(maxvals, axis=(2, 3))).nonzero())
# In [82]: (windows == np.expand_dims(maxvals, axis = (2, 3))).nonzero()
# This gives 4 arrays:
# First two are the window indices, e.g.
# (array([0, 0, 0, 1, 1, 1]),
# array([0, 1, 2, 0, 1, 2]),
# last two are the relative indices (within each window)
# array([0, 0, 1, 1, 1, 1]),
# array([1, 1, 1, 1, 1, 0]))
window_positions, relative_positions = indx.reshape((2, 2, -1))
# Multiply the first two by the window size to get the absolute indices
# of the top lefts of the windows
window_offsets = np.array([row_window, col_window]).reshape((2, 1))
# Then add the last two to get the relative indices
rows, cols = relative_positions + window_positions * window_offsets
return rows, cols