Convertir tipos de letra numpy a tipos de python nativos

Si tengo un dtype numpy, ¿cómo lo convierto automáticamente al tipo de datos de python más cercano? Por ejemplo,

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

Podría intentar crear un mapeo de todos estos casos, pero, ¿el número proporciona alguna forma automática de convertir sus tipos de datos en los tipos de python nativos más cercanos posibles? Este mapeo no necesita ser exhaustivo, pero debe convertir los tipos de datos comunes que tienen un análogo de python cerrado. Creo que esto ya sucede en algún lugar en numpy.

Use val.item() para convertir la mayoría de los valores NumPy a un tipo de Python nativo:

 import numpy as np # for example, numpy.float32 -> python float val = np.float32(0) pyval = val.item() print(type(pyval)) #  # and similar... type(np.float64(0).item()) #  type(np.uint32(0).item()) #  type(np.int16(0).item()) #  type(np.cfloat(0).item()) #  type(np.datetime64(0, 'D').item()) #  type(np.datetime64('2001-01-01 00:00:00').item()) #  type(np.timedelta64(0, 'D').item()) #  ... 

(Otro método es np.asscalar(val) , sin embargo, está en desuso desde NumPy 1.16).


Para los curiosos, para construir una tabla de conversiones de escalas de matriz NumPy para su sistema:

 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 

Hay algunos tipos NumPy que no tienen un equivalente nativo de Python en algunos sistemas, incluidos: clongdouble , clongfloat , complex192 , complex256 , float128 , longcomplex , longdouble y longfloat . Estos deben convertirse a su equivalente NumPy más cercano antes de usar .item() .

Me encontré con un conjunto mixto de tipos numpy y python estándar. como todos los tipos numpy se derivan de numpy.generic , aquí es cómo puede convertir todo a tipos estándar de python:

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

Qué tal si:

 In [51]: dict([(d, type(np.zeros(1,d).tolist()[0])) for d in (np.float32,np.float64,np.uint32, np.int16)]) Out[51]: {: , : , : , : } 

Si desea convertir (numpy.array O numpy escalar O tipo nativo OR numpy.darray) A tipo nativo, simplemente puede hacer:

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

tolist convertirá su escalar o matriz al tipo nativo de Python. La función lambda predeterminada se ocupa del caso en el que el valor ya es nativo.

También puede llamar al método item() del objeto que desea convertir:

 >>> from numpy import float32, uint32 >>> type(float32(0).item())  >>> type(uint32(0).item())  

Creo que puedes escribir una función de conversión de tipo general así:

 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) >> (, ) print get_type_convert(np.float64) >> (, ) 

Esto significa que no hay listas fijas y su código se escalará con más tipos.

tolist() es un enfoque más general para lograr esto. Funciona en cualquier dtype primitivo y también en matrices o matrices.

Realmente no produce una lista si se llama desde tipos primitivos:

numpy == 1.15.2

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

numpy mantiene esa información en una asignación expuesta como typeDict para que pueda hacer algo como lo siguiente:

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

Si quieres los tipos reales de python en lugar de sus nombres, puedes hacer lo siguiente:

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

Traducir todo el ndarray en lugar de un objeto de datos de unidad:

 def trans(data): """ translate numpy.int/float into python native data type """ result = [] for i in data.index: # i = data.index[0] d0 = data.iloc[i].values d = [] for j in d0: if 'int' in str(type(j)): res = j.item() if 'item' in dir(j) else j elif 'float' in str(type(j)): res = j.item() if 'item' in dir(j) else j else: res = j d.append(res) d = tuple(d) result.append(d) result = tuple(result) return result 

Sin embargo, toma algunos minutos cuando se manejan grandes marcos de datos. También estoy buscando una solución más eficiente. Espero una mejor respuesta.