numpy配列:入力として指定された行と列のセットで固定ウィンドウ内のargmaxを計算する効率的な方法

yang5

2D配列arrrowscols定義された位置のセット、および形状のウィンドウがあると仮定します(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リスト内包表記を使用する代わりに、これを行うより速い方法があるかどうか興味がありました

これは「形態学的拡張」に似ていますが、ここでは配列セルのサブセット上にあり、インデックスが必要です。

Divakar

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]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ