2017-10-26 13 views
1

numpy 배열을 해시 가능하게 만드는 한 가지 방법은 읽기 전용으로 설정하는 것입니다. 이것은 과거에 저에게 효과적이었습니다. 그러나 튜플에서 그런 열세 배열을 사용할 때, 전체 튜플은 더 이상 해시 가능하지 않습니다. 이해할 수 없습니다. 다음은 문제를 설명하기 위해 함께 사용한 샘플 코드입니다.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' 

내가 내 튜플 해쉬을 위해 할 수있는 이유는 파이썬이 처음부터이 문제가 표시되는 이유는 무엇입니까?

+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입니다.

지금
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 [11]: %timeit hash(y.tostring()) 

정의 클래스를 튜플을 사용하기보다는이다

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

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

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

이것은 파이썬으로 느껴집니다. 또한 나중에 numpy.fromstring()을 래핑하는 함수로 변환 할 수도 있습니다.이 함수는 나중에 필요할 것입니다. – Demento

1

당신이 주장하는

numpy 배열을 해시 가능하게 만드는 한 가지 방법은 읽기 전용으로 설정하는 것입니다.

하지만 사실은 그렇지 않습니다. 배열을 읽기 전용으로 설정하면 읽기 전용이됩니다. 여러 가지 이유로 배열을 해시 가능하게 만들지 않습니다.

첫 번째 이유는 writeable 플래그가 False으로 설정된 배열이 여전히 변경 가능하다는 것입니다. 먼저 writeable=True을 다시 설정하고 글쓰기를 다시 시작하거나 writeableFalse 인 동안에도 shape을 다시 할당하는 것과 같은 이국적인 작업을 수행 할 수 있습니다. 둘째, 배열 자체를 건드리지 않고도 writeable=True이있는 다른 뷰를 통해 데이터를 변경할 수 있습니다. == 부울을 반환해야하고, 동치 관계 여야합니다 - hashability는 의미가 할

>>> 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