データをbytearrayに最初にコピーせずにnumpy配列をハッシュしたいハッシュ可能numpyメモリビューを取得する
具体的には、一意の行を持つ連続した読み取り専用2次元int64 numpy配列A
があります。具体的には、のは言わせて:
A = np.array([[1, 2], [3, 4], [5, 6]])
A.setflags(write=False)
私はA
のスライスに値が同じだ任意の配列ap
をマッピングし、一定時間関数を作りたい、例えばA[i]
、そのインデックスi
へ。例えば
lookup = {a: i for i, a in enumerate(A)}
残念ながらnumpyの配列はハッシュ可能ではありません。
foo(np.array([1, 2])) == 0
foo(np.array([3, 4])) == 1
foo(np.array([5, 6])) == 2
自然な選択のような辞書を作ることです。ハッシュnumpy配列にはwaysがありますが、理想的には、等価を保持して手動での衝突検出を行わずに辞書で使用できるようにしたいと思います。
参照記事は、私が何ができることを指摘ん:
lookup = {a.data.tobytes(): i for i, a in enumerate(A)}
def foo(ap):
return lookup[ap.data.tobytes()]
tobytes
方法は、データのコピーを返します。ただし、したがって、メモリ使用量を倍増、a.data
で指されます。
私は何をしてみたいことのようなものです:は理想的、代わりに、配列オブジェクトまたはそのバイトのコピーの基本的なメモリへのポインタを使用していますが、a.dtype == int
以来でしょう
lookup = {a.data: i for i, a in enumerate(A)}
def foo(ap):
return lookup[ap.data]
この
ValueError: memoryview: hashing is restricted to formats 'B', 'b' or 'c'
これは結構ですが、私たちは今、我々が持っている、Aview = A.view(np.byte)
それをキャストすることができます:これはで失敗
しかし、それはまだでエラー:
TypeError: unhashable type: 'numpy.ndarray'
(thisに触発された)可能な解決策を定義するには次のようになります。
class _wrapper(object)
def __init__(self, array):
self._array = array
self._hash = hash(array.data.tobytes())
def __hash__(self):
return self._hash
def __eq__(self, other):
return self._hash == other._hash and np.all(self._array == other._array)
lookup = {_wrapper(a): i for i, a in enumerate(A)}
def foo(ap):
return lookup[_wrapper(ap)]
しかし、これは洗練さそうです。 Pythonにメモリビューをbytearrayとして解釈させ、バイトスクリプトにコピーを作成するか、numpyを中断してハッシュを中止する必要なしに普通にハッシュするように指示する方法はありますか?
私が試した他のもの:
Aのフォーマットは、私は異なる整数に各行をマッピングすることができないが、非常に大きな
A
可能アレイの空間がnp.iinfo(int).max
より大きい、及び私はPythonの整数型を使うことができますが、メモリをハッシングするよりも100倍遅いです。でもA.flags.writeable == False
、A[0].flags.writeable == True
けれども、しかしAview = A.view(np.void(A.shape[1] * A.itemsize)).squeeze()
:
は、私はまた、のようなものをやってみました。試してみると
hash(A[0])
のpythonはTypeError: unhashable type: 'writeable void-scalar'
を発生させます。私はスカラーを読み取り専用としてマークすることが可能かどうか確信しています。そうでなければ、他のほとんどのスカラーがハッシュ可能なように見えるにもかかわらず、空のスカラーをハッシュします。
配列全体をキーまたはその要素として使用しようとしていますか? – hpaulj
@ hpaulj配列のスライスをハッシュしようとしています。私は、私がより明確にしたものを作るべきであるという質問に対する重要な更新を行った。 – Erik