2017-10-26 8 views
1

numpy配列をハッシュ可能にする1つの方法は、それを読み取り専用に設定することです。これは過去に私のために働いてきました。しかし、タプルでこのような数値配列を使うと、タプル全体がもはやハッシュ可能ではなくなります。私は理解しません。numpy配列を含むタプルをハッシュ可能にするには?

import numpy as np 

npArray = np.ones((1,1)) 
npArray.flags.writeable = False 
print(npArray.flags.writeable) 

keySet = (0, npArray) 
print(keySet[1].flags.writeable) 

myDict = {keySet : 1} 

最初に単純なnumpy配列を作成し、それを読み取り専用に設定します。次に、それをタプルに追加して、まだ読み込み専用かどうかを確認します(これはそれです)。

タプルを辞書のキーとして使用する場合は、エラーTypeError: unhashable type: 'numpy.ndarray'が返されます。ここで

は私のサンプルコードの出力です:

False 
False 
Traceback (most recent call last): 
    File "test.py", line 10, in <module> 
    myDict = {keySet : 1} 
TypeError: unhashable type: 'numpy.ndarray' 

は、私は私のタプルがハッシュ可能にするために何ができるのと、なぜPythonは最初の場所でこの挙動を示すのか?

+0

'writeable'フラグを' False'に設定すると、配列はハッシュ可能になるという考えをどこから得ましたか?タプルを画像に取り込む前でさえ、これはうまくいかない。 – user2357112

+0

numpyの配列には、必要なハッシュ方法( '__hash__'のようなもの)がありません。 – hpaulj

+0

方法はここに記述されています:https://stackoverflow.com/questions/16589791/most-efficient-property-to-hash-for-numpy-array – Demento

答えて

1

hash a numpy array is likely tostringへの最速の方法。あなたは何ができるか

In [11]: %timeit hash(y.tostring()) 

タプルがクラスを定義し使用するのではなく次のとおりです。

class KeySet(object): 
    def __init__(self, i, arr): 
     self.i = i 
     self.arr = arr 
    def __hash__(self): 
     return hash((self.i, hash(self.arr.tostring()))) 

今、あなたは辞書でそれを使用することができます。

In [21]: ks = KeySet(0, npArray) 

In [22]: myDict = {ks: 1} 

In [23]: myDict[ks] 
Out[23]: 1 
+0

これは速い答えのためにpythonic、thxと感じます!また、後でnumpy.fromstring()をラップする関数を使用して変換することもできます。これは後で必要になります。 – Demento

1

あなたは

と主張

numpy配列をハッシュ可能にする1つの方法は、読み取り専用に設定することです

実際にはそうではありません。配列を読み取り専用に設定すると、読み取り専用になります。複数の理由から、配列をハッシュ可能にしません。

最初の理由は、writeableフラグがFalseに設定されている配列がまだ変更可能であることです。まず、writeable=Trueを再度設定して書き込みを再開するか、writeableFalseの場合でも、shapeを再割り当てするようなエキゾチックなことを行うことができます。第二に、配列自体に触れることなく、writeable=Trueという別のビューでデータを変更することができます。

>>> x = numpy.arange(5) 
>>> y = x[:] 
>>> x.flags.writeable = False 
>>> x 
array([0, 1, 2, 3, 4]) 
>>> y[0] = 5 
>>> x 
array([5, 1, 2, 3, 4]) 

第二に、意味のあるものにするハッシュ可能のため、オブジェクトは最初equatableなければならない - ブール値を返す必要があり、及び同値関係でなければならない==。 NumPy配列はそれをしません。ハッシュ値の目的は、等しいオブジェクトをすばやく見つけることですが、オブジェクトにも同等の概念が組み込まれていない場合でも、ハッシュを提供する点はあまりありません。


あなたは配列を含むハッシュ可能なタプルを取得しません。ハッシュ可能な配列を取得するつもりはありません。あなたが得ることができる最も近いのは、配列のデータの他の表現をタプルに入れることです。

+0

+1、内部の説明に感謝します。配列をハッシュするというアイデアがテーブルから外れていれば、最初に文字列に変換する必要があります。 – Demento

関連する問題