Constructing a Python set from a Numpy matrix

前端 未结 6 1078
面向向阳花
面向向阳花 2020-12-06 00:17

I\'m trying to execute the following

>> from numpy import *
>> x = array([[3,2,3],[4,4,4]])
>> y = set(x)
TypeError: unhashable type: \'num         


        
6条回答
  •  执念已碎
    2020-12-06 01:06

    I liked xperroni's idea. But I think implementation can be simplified using direct inheritance from ndarray instead of wrapping it.

    from hashlib import sha1
    from numpy import ndarray, uint8, array
    
    class HashableNdarray(ndarray):
        def __hash__(self):
            if not hasattr(hasattr, '__hash'):
                self.__hash = int(sha1(self.view(uint8)).hexdigest(), 16)
            return self.__hash
    
        def __eq__(self, other):
            if not isinstance(other, HashableNdarray):
                return super(HashableNdarray, self).__eq__(other)
            return super(HashableNdarray, self).__eq__(super(HashableNdarray, other)).all()
    

    NumPy ndarray can be viewed as derived class and used as hashable object. view(ndarray) can be used for back transformation, but it is not even needed in most cases.

    >>> a = array([1,2,3])
    >>> b = array([2,3,4])
    >>> c = array([1,2,3])
    >>> s = set()
    
    >>> s.add(a.view(HashableNdarray))
    >>> s.add(b.view(HashableNdarray))
    >>> s.add(c.view(HashableNdarray))
    >>> print(s)
    {HashableNdarray([2, 3, 4]), HashableNdarray([1, 2, 3])}
    >>> d = next(iter(s))
    >>> print(d == a)
    [False False False]
    >>> import ctypes
    >>> print(d.ctypes.data_as(ctypes.POINTER(ctypes.c_double)))
    <__main__.LP_c_double object at 0x7f99f4dbe488>
    

提交回复
热议问题