2016-03-29 8 views
1

2 3次元numpyの配列を比較した私は2つのnumpyの配列があります。Pythonは

A.shape = (nA,x,y) 

B.shape = (nB,x,y). 

を私は私ができる知っているすべてのサブアレイは、このような

A(i,:,:) == B(j,:,:). 

ことを見つけたいですループの2倍を書いて使用する

np.array_equal(A(i,:,:),B(j,:,:) 

しかし、より効率的な方法がありますか?

答えて

1

後でユニークなサブアレイが見つからないので、配列のいずれかをループするだけでよいので、単純なリストの理解でこれを行うことができます。あなたが唯一の全体ではなく部分配列を格納するインデックスが必要な場合

subarrays = [x for x in A if x in B] 

、あなたが行うことができます:

スティーブンRoukのソリューションを活用し
indices = [x[0] for x in enumerate(A) if x[1] in B] 
+0

はのインデックスを格納するリスト内包を使用して方法はあります実際のデータの代わりにマッチ? – user3731622

+1

私の答えはそれをどうやって編集しました。 –

1

は、ここに等しいサブアレイのためのインデックスを取得するための方法であり、 :

indicesForMatches = [(i,j) for i,subArrayOfA in enumerate(A) for j,subArrayOfB in enumerate(B) if np.array_equal(subArrayOfA,subArrayOfB)] 
1

あなたがそうのように、ベクトル化ソリューションのためのNumPy broadcastingを使用することができます -

mask = ((A[:,None,:,:] == B).all(2)).all(2) 
A_idx,B_idx = np.where(mask) 
そのようにあなたは、二重の .all()用法を避け、マスクを取得するために reshapingを使用することができます

-

mask = (A.reshape(A.shape[0],1,-1) == B.reshape(B.shape[0],-1)).all(-1) 

サンプル実行 -

In [41]: # Setup input arrays and force some indices to be same between A and B 
    ...: nA = 4 
    ...: nB = 5 
    ...: x = 3 
    ...: y = 2 
    ...: 
    ...: A = np.random.randint(0,9,(nA,x,y)) 
    ...: B = np.random.randint(0,9,(nB,x,y)) 
    ...: 
    ...: A[2,:,:] = B[1,:,:] 
    ...: A[3,:,:] = B[4,:,:] 
    ...: 

In [42]: mask = ((A[:,None,:,:] == B).all(2)).all(2) 
    ...: A_idx,B_idx = np.where(mask) 
    ...: 

In [43]: A_idx, B_idx 
Out[43]: (array([2, 3]), array([1, 4])) 

In [44]: mask = (A.reshape(A.shape[0],1,-1) == B.reshape(B.shape[0],-1)).all(-1) 
    ...: A_idx,B_idx = np.where(mask) 
    ...: 

In [45]: A_idx, B_idx 
Out[45]: (array([2, 3]), array([1, 4]))