首页 文章

将numpy dtypes转换为本机python类型

提问于
浏览
145

如果我有一个numpy dtype,如何自动将其转换为最接近的python数据类型?例如,

numpy.float32 -> "python float"
numpy.float64 -> "python float"
numpy.uint32  -> "python int"
numpy.int16   -> "python int"

我可以尝试提出所有这些情况的映射,但是numpy是否提供了一些自动方式将其dtypes转换为最接近的可能的本机python类型?这种映射不一定是详尽无遗的,但它应该转换具有close python模拟的常见dtypes . 我认为这已经发生在numpy的某个地方了 .

8 回答

  • 4

    发现自己有混合的numpy类型和标准python . 因为所有numpy类型派生自 numpy.generic ,以下是如何将所有内容转换为python标准类型:

    if isinstance(obj, numpy.generic):
        return numpy.asscalar(obj)
    
  • 197

    怎么样:

    In [51]: dict([(d, type(np.zeros(1,d).tolist()[0])) for d in (np.float32,np.float64,np.uint32, np.int16)])
    Out[51]: 
    {<type 'numpy.int16'>: <type 'int'>,
     <type 'numpy.uint32'>: <type 'long'>,
     <type 'numpy.float32'>: <type 'float'>,
     <type 'numpy.float64'>: <type 'float'>}
    
  • 6

    如果要将(numpy.array或numpy标量或本机类型OR numpy.darray)转换为本机类型,您只需执行以下操作:

    converted_value = getattr(value, "tolist", lambda x=value: x)()
    

    tolist会将您的标量或数组转换为python本机类型 . 默认的lambda函数负责处理值已经是本机的情况 .

  • 1

    您还可以调用要转换的对象的item() method

    >>> from numpy import float32, uint32
    >>> type(float32(0).item())
    <type 'float'>
    >>> type(uint32(0).item())
    <type 'long'>
    
  • 9

    使用a.item()np.asscalar(a)将大多数NumPy值转换为本机Python类型:

    import numpy as np
    # examples using a.item()
    type(np.float32(0).item()) # <type 'float'>
    type(np.float64(0).item()) # <type 'float'>
    type(np.uint32(0).item())  # <type 'long'>
    # examples using np.asscalar(a)
    type(np.asscalar(np.int16(0)))   # <type 'int'>
    type(np.asscalar(np.cfloat(0)))  # <type 'complex'>
    type(np.asscalar(np.datetime64(0, 'D')))  # <type 'datetime.datetime'>
    type(np.asscalar(np.timedelta64(0, 'D'))) # <type 'datetime.timedelta'>
    ...
    

    阅读更多in the NumPy manual . 为了好奇,为您的系统构建一个转换表:

    for name in dir(np):
        obj = getattr(np, name)
        if hasattr(obj, 'dtype'):
            try:
                if 'time' in name:
                    npn = obj(0, 'D')
                else:
                    npn = obj(0)
                nat = npn.item()
                print('{0} ({1!r}) -> {2}'.format(name, npn.dtype.char, type(nat)))
            except:
                pass
    

    有些NumPy类型在某些系统上没有本机Python等效类型,包括: clongdouble774793complex192complex256float128longcomplexlongdoublelongfloat . 在使用 asscalar 之前,需要将它们转换为最接近的NumPy等效值 .

  • 7

    我想你可以像这样编写通用类型转换函数:

    import numpy as np
    
    def get_type_convert(np_type):
       convert_type = type(np.zeros(1,np_type).tolist()[0])
       return (np_type, convert_type)
    
    print get_type_convert(np.float32)
    >> (<type 'numpy.float32'>, <type 'float'>)
    
    print get_type_convert(np.float64)
    >> (<type 'numpy.float64'>, <type 'float'>)
    

    这意味着没有固定列表,您的代码将扩展为更多类型 .

  • 32

    numpy将映射中的信息显示为 typeDict ,因此您可以执行以下操作::

    >>> import __builtin__
    >>> import numpy as np
    >>> {v: k for k, v in np.typeDict.items() if k in dir(__builtin__)}
    {numpy.object_: 'object',
     numpy.bool_: 'bool',
     numpy.string_: 'str',
     numpy.unicode_: 'unicode',
     numpy.int64: 'int',
     numpy.float64: 'float',
     numpy.complex128: 'complex'}
    

    如果你想要实际的python类型而不是它们的名字,你可以做::

    >>> {v: getattr(__builtin__, k) for k, v in np.typeDict.items() if k in vars(__builtin__)}
    {numpy.object_: object,
     numpy.bool_: bool,
     numpy.string_: str,
     numpy.unicode_: unicode,
     numpy.int64: int,
     numpy.float64: float,
     numpy.complex128: complex}
    
  • 1

    tolist() 是实现这一目标的更通用的方法 . 它适用于任何原始dtype以及数组或矩阵 .

    如果从原始类型调用,我实际上不会产生一个列表:

    numpy == 1.15.2

    >>> import numpy as np
    
    >>> np_float = np.float64(1.23)
    >>> print(type(np_float), np_float)
    <class 'numpy.float64'> 1.23
    
    >>> listed_np_float = np_float.tolist()
    >>> print(type(listed_np_float), listed_np_float)
    <class 'float'> 1.23
    
    >>> np_array = np.array([[1,2,3.], [4,5,6.]])
    >>> print(type(np_array), np_array)
    <class 'numpy.ndarray'> [[1. 2. 3.]
     [4. 5. 6.]]
    
    >>> listed_np_array = np_array.tolist()
    >>> print(type(listed_np_array), listed_np_array)
    <class 'list'> [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
    

相关问题