2D配列arr
、rows
とcols
で定義された位置のセット、および形状のウィンドウがあると仮定します(5, 1)
。の場合(i, j)
、内の最大値のインデックスが必要arr[i-2:i+2, j]
です。すべての入力(i, j)
ペアに対して繰り返します。
import numpy as np
def get_max_index(arr, i, j, stride):
nr, nc = arr.shape
i_low = max(0, i - stride)
i_up = min(i + stride, nr)
idx = np.argmax(arr[i_low:i_up, j])
# transform back to original index.
return i_low + idx, j
# Given numpy array
arr = np.array([
[1,2,3,6,7],
[4,5,6,15,8],
[7,8,9,24,9],
[1,1,1,3,10],
[2,2,2,6,11],
[3,3,3,9,12],
[4,4,4,4,42]
])
# Rows and columns at which the windows will be centered.
rows = np.array([2, 4, 6, 6])
cols = np.array([1, 1, 3, 4])
# Measure corresponding to window of size 5
stride = 2
# Apply the function on the input rows and cols.
res = [get_max_index(arr, i, j, stride) for i, j in zip(rows, cols)]
assert res == [(2, 1), (2, 1), (5, 3), (6, 4)]
numpy
リスト内包表記を使用する代わりに、これを行うより速い方法があるかどうか興味がありました。
これは「形態学的拡張」に似ていますが、ここでは配列セルのサブセット上にあり、インデックスが必要です。
np.lib.stride_tricks.as_strided
ベースscikit-image's view_as_windows
を活用して、ウィンドウビューを最小値が埋め込まれたバージョンの入力に(境界の場合を考慮して)取得し、それらのargmax値を取得して、指定された行に対してオフセットすることができます。
したがって、実装は次のようになります-
from skimage.util.shape import view_as_windows
def windowed_argmax(arr, rows, cols, stride):
# Get full window extent
W = 2*stride+1
# Pad with minimum value, so that on boundaries we will skip those
a = np.pad(arr,((stride,stride),(0,0)),'constant',constant_values=arr.min()-1)
# Get sliding windows
w = view_as_windows(a,(W,1))[...,0]
# Index into those specific rows, cols positions; get argmax, offset back
return np.c_[rows+w[rows,cols].argmax(1)-stride,cols]
サンプル実行-
In [75]: arr
Out[75]:
array([[ 1, 2, 3, 6, 7],
[ 4, 5, 6, 15, 8],
[ 7, 8, 9, 24, 9],
[ 1, 1, 1, 3, 10],
[ 2, 2, 2, 6, 11],
[ 3, 3, 3, 9, 12],
[ 4, 4, 4, 4, 42]])
In [76]: rows
Out[76]: array([2, 4, 6, 6])
In [77]: cols
Out[77]: array([1, 1, 3, 4])
In [78]: windowed_argmax(arr, rows, cols, stride=2)
Out[78]:
array([[2, 1],
[2, 1],
[5, 3],
[6, 4]])
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加