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

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

我可以尝试提出所有这些情况的映射,但是numpy是否提供了一些自动的方法来将其dtypes转换为尽可能接近的本机python类型?这种映射不需要是详尽的,但它应该转换具有类似python的常见dtype。我想这已经在numpy的某个地方发生了。


当前回答

Tolist()是一种更通用的实现方法。它适用于任何基元dtype,也适用于数组或矩阵。

如果从基本类型调用I,实际上不会产生一个列表:

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

其他回答

我的方法有点强硬,但似乎适用于所有情况:

def type_np2py(dtype=None, arr=None):
    '''Return the closest python type for a given numpy dtype'''

    if ((dtype is None and arr is None) or
        (dtype is not None and arr is not None)):
        raise ValueError(
            "Provide either keyword argument `dtype` or `arr`: a numpy dtype or a numpy array.")

    if dtype is None:
        dtype = arr.dtype

    #1) Make a single-entry numpy array of the same dtype
    #2) force the array into a python 'object' dtype
    #3) the array entry should now be the closest python type
    single_entry = np.empty([1], dtype=dtype).astype(object)

    return type(single_entry[0])

用法:

>>> type_np2py(int)
<class 'int'>

>>> type_np2py(np.int)
<class 'int'>

>>> type_np2py(str)
<class 'str'>

>>> type_np2py(arr=np.array(['hello']))
<class 'str'>

>>> type_np2py(arr=np.array([1,2,3]))
<class 'int'>

>>> type_np2py(arr=np.array([1.,2.,3.]))
<class 'float'>

如果你有一个numpy类型的数组list_numpy_numbers,执行以下操作:

list_native_numbers = [i.item() for i in list_numpy_numbers]

如果你想转换(numpy。数组或numpy标量或本机类型或numpy.darray)本机类型你可以简单地做:

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

Tolist会将标量或数组转换为python原生类型。默认的lambda函数处理值已经是本机的情况。

对于那些不需要自动转换并且知道值的numpy dtype的人来说,关于数组标量的一个旁注:

Array scalars differ from Python scalars, but for the most part they can be used interchangeably (the primary exception is for versions of Python older than v2.x, where integer array scalars cannot act as indices for lists and tuples). There are some exceptions, such as when code requires very specific attributes of a scalar or when it checks specifically whether a value is a Python scalar. Generally, problems are easily fixed by explicitly converting array scalars to Python scalars, using the corresponding Python type function (e.g., int, float, complex, str, unicode).

因此,在大多数情况下,可能根本不需要转换,可以直接使用数组标量。效果应该与使用Python scalar相同:

>>> np.issubdtype(np.int64, int)
True
>>> np.int64(0) == 0
True
>>> np.issubdtype(np.float64, float)
True
>>> np.float64(1.1) == 1.1
True

但是,如果出于某种原因,需要显式转换,则使用相应的Python内置函数是正确的方法。正如另一个答案所示,它也比数组标量item()方法快。

numpy将该信息保存在一个暴露为typeDict的映射中,因此您可以执行如下操作:

>>> import __builtin__ as builtins  # if python2
>>> import builtins                 # if python3

然后::

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

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

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