2016-12-26 8 views
2

与えられた次元に沿った(i + 1)番目から(i + n)番目のスライスと適切な次元の与えられたテンソルが比較されるかどうかを知りたいオペレータを適用する。次元に沿ったローリングウィンドウの複数値の比較

つまり、もっと具体的には、2次元の配列があり、5つの値を比較したいとします。次の5つの値のすべてが第1の値よりも高い場合、第1の列が第1の列にある真理値の配列を作成する必要があります。同様に列と次の行との間で、第1列は3列目から8列目の第1列と行2列の第1列との値の比較を有する。

など。

[[1, 1], 
[2, 2], 
[3, 3], 
[4, 4], 
[5, 5], 
[6, 0], 
[7, 1], 
[8, 2]] 

を与える必要があり:

[[True, False], 
[True, False], 
[True, False]] 

オペレータが5で比較するとアイテムの数(全次の5つの項目が以上でなければならないことを伴う)all >=であり、比較が行であります(軸0)。

NumpyやPandasでこれをやりたいのですが、Numpyが好きです。

+0

あなたは、特定のテンソル(例えば、2次元配列)と所望の出力との例を提供していただけますか? – Fomalhaut

+0

例を追加しました。 –

答えて

1

1つのトリックはScipy's 1D minimum filterを使用し、現在の要素と現在の要素の後に開始する間隔の最小値と現在の要素を比較します。長さはnです。その間隔の最小値を確認して、基本的にすべての要素に対してgreater-thanをチェックしています。

したがって、我々はそうのように、解決策を持っているでしょう -

from scipy.ndimage.filters import minimum_filter1d as minf 

def rolling_comparison(a, W): 
    HW = (W-1)//2 # Half window size for offsetting kernel in min filter 
    v = minf(a,W,origin=-HW) 
    return v[:,1:] > a[:,:-1] 

ここでは、さまざまなウィンドウサイズのサンプルテストだ -

In [245]: a 
Out[245]: 
array([[59, 86, 77, 31, 91, 88, 13, 77, 77, 39], 
     [12, 63, 98, 21, 69, 89, 93, 38, 52, 62], 
     [29, 58, 42, 74, 22, 27, 23, 40, 37, 11]]) 

In [246]: rolling_comparison(a, W=3) 
Out[246]: 
array([[False, False, False, False, False, False, True, False, False], 
     [ True, False, False, True, False, False, False, True, False], 
     [ True, False, False, False, True, False, False, False, False]]) 

In [247]: rolling_comparison(a, W=5) 
Out[247]: 
array([[False, False, False, False, False, False, True, False, False], 
     [ True, False, False, True, False, False, False, False, False], 
     [False, False, False, False, False, False, False, False, False]]) 

In [248]: rolling_comparison(a, W=7) 
Out[248]: 
array([[False, False, False, False, False, False, False, False, False], 
     [ True, False, False, True, False, False, False, False, False], 
     [False, False, False, False, False, False, False, False, False]]) 

今すぐサンプルケース

を解決するには、列挙されたアプローチは、2D配列の各行に沿って動作します。それは、列単位で動作させるようにしているようです。また、境界線の境界要素であるreflectsの場合は、有効な要素のみに興味があります。したがって、あなたのケースに合わせて、transposeを使用し、最初の半分のウィンドウサイズでクリップする必要があります。

このように、あなたのケースに適応、我々は持っているだろう -

In [82]: a 
Out[82]: 
array([[1, 1], 
     [2, 2], 
     [3, 3], 
     [4, 4], 
     [5, 5], 
     [6, 6], # Made the second elem as 6 for variety 
     [7, 1], 
     [8, 2]]) 

In [83]: rolling_comparison(a.T, W=5).T[:3] # 3 is half window size for 5 
Out[83]: 
array([[ True, True], 
     [ True, False], 
     [ True, False]], dtype=bool) 
+0

+1、多くのお返事をいただきありがとうございます。これはいくつか明快ですが、演算子が '=='なら 'minf'が機能しないかもしれないことを指摘したいだけでした。 –

+0

また、 'W = 5'と' W = 7'は 'W = 3'の場合よりも要素数が徐々に少なくなるはずです。 –

+0

@ SumindaSirinathS.Dharmasena郵便で述べたように、最小フィルタは、より大きい問題のために働くことを排他的に意図しています。また、このソリューションは、各行に沿って作業していることを前提としていますが、サンプルでは各列に沿って処理しています。したがって、あなたのケースに適応するには、それを転置してください。 – Divakar

関連する問題