将numpy dtypes转换为本地pythontypes

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

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

我可以试着想出所有这些情况的映射,但numpy提供了一些自动的方法,将其dtype转换为最接近的本地pythontypes? 这个映射不一定是详尽的,但是它应该转换具有相近pythontypes的常见dtypes。 我认为这已经发生在某个地方了。

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

 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))) # <type 'datetime.datetime'> type(np.asscalar(np.timedelta64(0))) # <type 'datetime.timedelta'> ... 

阅读NumPy手册 。 为了好奇,为您的系统build立一个转换表:

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

有些NumPytypes在某些系统上没有本地Python等价物,包括: clongdoubleclongfloatcomplex192float128longcomplexlongdoublelongdoublelongfloat 。 在使用asscalar之前,这些需要转换成最接近的NumPy等价物。

发现自己有一些混合的numpytypes和标准的Python。 因为所有的numpytypes都是从numpy.generic派生的, numpy.generic是如何将所有的东西都转换成python的标准types:

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

怎么样:

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

我认为你可以只写一般的types转换function,如下所示:

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

这意味着没有固定的列表,你的代码将会扩展更多的types。

你也可以调用你想要转换的对象的item()方法 :

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

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

如果你想要的是实际的pythontypes而不是他们的名字,你可以这样做:

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

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

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

tolist会将您的标量或数组转换为Python本机类​​型。 默认的lambda函数负责处理value已经是native的情况。