numpy ndarray hashability

前端 未结 2 962
灰色年华
灰色年华 2021-01-11 13:22

I have some problems understanding how numpy objects hashability is managed.

>>> import numpy as np
>>> class Vector(np.ndarray):
...     p         


        
2条回答
  •  半阙折子戏
    2021-01-11 14:04

    This is not a clear answer, but here is some track to follow to understand this behavior.

    I refer here to the numpy code of the 1.6.1 release.

    According to numpy.ndarray object implementation (look at, numpy/core/src/multiarray/arrayobject.c), hash method is set to NULL.

    NPY_NO_EXPORT PyTypeObject PyArray_Type = {
    #if defined(NPY_PY3K)
        PyVarObject_HEAD_INIT(NULL, 0)
    #else
        PyObject_HEAD_INIT(NULL)
        0,                                          /* ob_size */
    #endif
        "numpy.ndarray",                            /* tp_name */
        sizeof(PyArrayObject),                      /* tp_basicsize */
        &array_as_mapping,                          /* tp_as_mapping */
        (hashfunc)0,                                /* tp_hash */
    

    This tp_hash property seems to be overridden in numpy/core/src/multiarray/multiarraymodule.c. See DUAL_INHERIT, DUAL_INHERIT2 and initmultiarray function where tp_hash attribute is modified.

    Ex: PyArrayDescr_Type.tp_hash = PyArray_DescrHash

    According to hashdescr.c, hash is implemented as follow:

    * How does this work ? The hash is computed from a list which contains all the
    * information specific to a type. The hard work is to build the list
    * (_array_descr_walk). The list is built as follows:
    *      * If the dtype is builtin (no fields, no subarray), then the list
    *      contains 6 items which uniquely define one dtype (_array_descr_builtin)
    *      * If the dtype is a compound array, one walk on each field. For each
    *      field, we append title, names, offset to the final list used for
    *      hashing, and then append the list recursively built for each
    *      corresponding dtype (_array_descr_walk_fields)
    *      * If the dtype is a subarray, one adds the shape tuple to the list, and
    *      then append the list recursively built for each corresponding type
    *      (_array_descr_walk_subarray)
    

提交回复
热议问题