質問
誰がこの問題に出くわしたことがありますか?次のような2つの配列があるとします
a = array([1,2,3,4,5,6])
b = array([1,4,5])
bに存在するaの要素を比較する方法はありますか?たとえば、
c = a == b # Wishful example here
print c
array([1,4,5])
# Or even better
array([True, False, False, True, True, False])
何百万もの要素があると時間がかかるため、ループを回避しようとしています。何か案は?
乾杯
解決
実際、これらのどれよりも簡単な解決策があります:
import numpy as np
a = array([1,2,3,4,5,6])
b = array([1,4,5])
c = np.in1d(a,b)
結果のcは次のようになります。
array([ True, False, False, True, True, False], dtype=bool)
他のヒント
np.intersect1dを使用します。
#!/usr/bin/env python
import numpy as np
a = np.array([1,2,3,4,5,6])
b = np.array([1,4,5])
c=np.intersect1d(a,b)
print(c)
# [1 4 5]
aまたはbに一意でない要素がある場合、np.intersect1dは間違った答えを与えることに注意してください。その場合は使用 np.intersect1d_nu。
np.setdiff1d、setxor1d、setmember1d、およびunion1dもあります。見る Numpy Example List with Doc
返信kaizer.seをありがとう。私が探していたものではありませんが、友人からの提案と、あなたが言ったことから、私は以下を思いつきました。
import numpy as np
a = np.array([1,4,5]).astype(np.float32)
b = np.arange(10).astype(np.float32)
# Assigning matching values from a in b as np.nan
b[b.searchsorted(a)] = np.nan
# Now generating Boolean arrays
match = np.isnan(b)
nonmatch = match == False
これは少し面倒なプロセスですが、ループの作成やループ付き織りの使用に勝ります。
乾杯
Numpyには、ソートされた一意の配列で動作し、必要なブール配列を正確に返すセット関数numpy.setmember1d()があります。入力配列が基準に一致しない場合は、設定された形式に変換し、結果の変換を反転する必要があります。
import numpy as np
a = np.array([6,1,2,3,4,5,6])
b = np.array([1,4,5])
# convert to the uniqued form
a_set, a_inv = np.unique1d(a, return_inverse=True)
b_set = np.unique1d(b)
# calculate matching elements
matches = np.setmea_set, b_set)
# invert the transformation
result = matches[a_inv]
print(result)
# [False True False False True True False]
編集: 残念ながら、numpyのsetmember1dメソッドは本当に非効率的です。提案した検索の並べ替えと割り当ての方法はより高速に動作しますが、直接割り当てることができる場合は、結果に直接割り当てて、不要なコピーの多くを避けることもできます。また、bにaにないものが含まれている場合、メソッドは失敗します。以下はこれらのエラーを修正します。
result = np.zeros(a.shape, dtype=np.bool)
idxs = a.searchsorted(b)
idxs = idxs[np.where(idxs < a.shape[0])] # Filter out out of range values
idxs = idxs[np.where(a[idxs] == b)] # Filter out where there isn't an actual match
result[idxs] = True
print(result)
私のベンチマークでは、これが91usであるのに対し、アプローチでは6.6ms、1M要素aおよび100要素bではnumpy setmember1dで109msとなっています。
ebresset、回答は、 aはbのサブセットです(aとbはソートされます)。そうでない場合、searchsortedは偽のインデックスを返します。同様のことをしなければならず、それをあなたのコードと組み合わせました:
# Assume a and b are sorted
idxs = numpy.mod(b.searchsorted(a),len(b))
idxs = idxs[b[idxs]==a]
b[idxs] = numpy.nan
match = numpy.isnan(b)
この例は、適切な要素を適切な場所に置くことよりも、配列内の存在をより重視するセットのような動作を意味します。 Numpyは、数学的な配列と行列を使用してこれを異なる方法で行い、正確な正しい場所にあるアイテムについてのみ通知します。あなたのためにそれを機能させることができますか?
>>> import numpy
>>> a = numpy.array([1,2,3])
>>> b = numpy.array([1,3,3])
>>> a == b
array([ True, False, True], dtype=bool)