2つの条件に準拠するための2つのnumpy配列の比較
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つのブール変数test1とtest2に値を割り当てたいと思います。
test1:A
列の1B
と同じ列の1の行の差が正確に1または2であるインスタンスが少なくとも1つありますか?その場合、test1 = True、それ以外の場合はFalse。
上記の例では、両方の配列の列0に2行離れた1があるため、test1 = Trueです。(列2には他のインスタンスもありますが、それは問題ではありません。必要なインスタンスは1つだけです。)
test2:の1つの値A
とB
すべての配列アドレスが異なりますか?その場合、test2 = True、それ以外の場合はFalse。
上記の例では、両方の配列にが含まれている[4,3] = 1
ため、test2 = Falseです。
私はこれを行うための効率的な方法を見つけるのに苦労しており、いくつかの支援をいただければ幸いです。
回答
これは、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
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
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))