2つの条件に準拠するための2つのnumpy配列の比較

Aug 18 2020

1と0で構成される、同じ形状の2つのnumpy配列AとBについて考えてみます。小さな例を示します。

A = [[1 0 0 1]         B = [[0 0 0 0]
     [0 0 1 0]              [0 0 0 0]
     [0 0 0 0]              [1 1 0 0]
     [0 0 0 0]              [0 0 1 0]
     [0 0 1 1]]             [0 1 0 1]]

ここで、次のように2つのブール変数test1test2に値を割り当てたいと思います。

test1A列の1Bと同じ列の1の行の差が正確に1または2であるインスタンスが少なくとも1つありますか?その場合、test1 = True、それ以外の場合はFalse。

上記の例では、両方の配列の列0に2行離れた1があるため、test1 = Trueです。(列2には他のインスタンスもありますが、それは問題ではありません。必要なインスタンスは1つだけです。)

test2:の1つの値ABすべての配列アドレスが異なりますか?その場合、test2 = True、それ以外の場合はFalse。

上記の例では、両方の配列にが含まれている[4,3] = 1ため、test2 = Falseです。

私はこれを行うための効率的な方法を見つけるのに苦労しており、いくつかの支援をいただければ幸いです。

回答

1 MadPhysicist Aug 18 2020 at 09:53

これは、2つの配列のエントリが同じ列に1要素離れているかどうかをテストする簡単な方法です(一方向のみ)。

(A[1:, :] * B[:-1, :]).any(axis=None)

だからあなたはすることができます

test1 = (A[1:, :] * B[:-1, :] + A[:-1, :] * B[1:, :]).any(axis=None) or (A[2:, :] * B[:-2, :] + A[:-2, :] * B[2:, :]).any(axis=None)

2番目のテストは、場所をインデックスに変換し、それらを積み重ね、を使用np.uniqueして重複の数をカウントすることで実行できます。配列に重複するインデックスが含まれることはないため、重複は2つの配列の同じインデックスからのみ取得できます。のflatnonzero代わりにを使用すると、計算をさらに高速化できますnonzero

test2 = np.all(np.unique(np.concatenate((np.flatnonzero(A), np.flatnonzero(B))), return_counts=True)[1] == 1)

より効率的なテストnp.intersect1dでも同様の方法で使用できます。

test2 = not np.intersect1d(np.flatnonzero(A), np.flatnonzero(B)).size
1 Ehsan Aug 18 2020 at 08:14

masked_arraysを使用でき、2番目のタスクでは次のことができます。

A_m = np.ma.masked_equal(A, 0)
B_m = np.ma.masked_equal(B, 0)

test2 = np.any((A_m==B_m).compressed())

そして、最初のタスクを実行する素朴な方法は次のとおりです。

test1 = np.any((np.vstack((A_m[:-1],A_m[:-2],A_m[1:],A_m[2:]))==np.vstack((B_m[1:],B_m[2:],B_m[:-1],B_m[:-2]))).compressed())

出力:

True
True
ArundeepChohan Aug 18 2020 at 09:56

Test2の場合:値1で類似のインデックスが見つかったかどうかを確認できます。

A =  np.array([[1, 0, 0, 1],[0, 0, 1, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 1, 1]])
B = np.array([[0, 0, 0, 0],[0, 0, 0, 0],[1, 1, 0, 0],[0, 0, 1, 0],[0, 1, 0, 1]])
print(len(np.intersect1d(np.flatnonzero(A==1),np.flatnonzero(B==1)))>0))