2012-02-26 16 views
109

Si tengo un tipo numpy, ¿cómo lo convierto automáticamente en el tipo de datos python más cercano? Por ejemplo,Convirtiendo los dtypes numpy a los tipos nativos de pitón

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

que podría tratar de llegar a un mapeo de todos estos casos, pero ¿numpy proporcionar alguna forma automática de la conversión de sus dtypes sobre los posibles tipos de pitón nativos más cercanos? Este mapeo no tiene que ser exhaustivo, pero debería convertir los dtypes comunes que tienen un análogo cercano de python. Creo que esto ya sucede en algún lugar en numpy.

Respuesta

149

uso ya sea a.item() o np.asscalar(a) para convertir la mayoría de los valores NumPy a un tipo de Python orígenes:

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

Leer más in the NumPy manual. Para los curiosos, para construir una tabla de conversiones 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 unos pocos tipos NumPy que no tienen equivalente nativa de Python en algunos sistemas, entre ellos: clongdouble, clongfloat, complex192, complex256, float128, longcomplex , longdouble y longfloat. Estos deben convertirse a su equivalente NumPy más cercano antes de usar asscalar.

9

¿Qué tal:

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

Menciono ese tipo de solución como una posibilidad al final de mi pregunta. Pero estoy buscando una solución sistemática en lugar de una codificada que solo cubra algunos de los casos. Por ejemplo, si numpy agrega más dtypes en el futuro, su solución se romperá.Entonces no estoy contento con esa solución. – conradlee

+0

El número de posibles dtypes no tiene límites. Considere 'np.dtype ('mint8')' para cualquier entero positivo 'm'. No puede haber un mapeo exhaustivo. (Tampoco creo que haya una función integrada para hacer esta conversión por ti. Podría estar equivocado, pero no lo creo :)) – unutbu

+2

Python asigna numerados dtypes a tipos de pitón, no estoy seguro de cómo, pero Me gustaría utilizar cualquier método que hagan. Creo que esto debe pasar para permitir, por ejemplo, la multiplicación (y otras operaciones) entre numpy dtypes y python types. Supongo que su método no hace un mapa exhaustivo de todos los tipos numpy posibles, pero al menos los más comunes donde tiene sentido. – conradlee

4

Creo que se puede escribir sólo función general Tipo convertido de este modo:

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

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

+0

¿Sabes dónde está el código fuente para la parte del método tolist() que mapea los tipos numpy a tipos de python? Eché un vistazo rápido pero no pude encontrarlo. – conradlee

+0

Esto es un poco un truco de lo que estoy haciendo es generar un 'numpy.ndarray' con 1 cero en él usando' ceros() 'y la llamada a la función' ndarrays' 'tolist()' para convertir a tipos nativos . Una vez en tipos nativos, pregunto por el tipo y lo devuelvo. 'tolist()' es una función del 'ndarray' –

+0

Sí, veo que --- funciona para lo que quiero y por eso acepté su solución. Pero me pregunto cómo tolist() hace su trabajo de decidir qué tipo de moldear, y no estoy seguro de cómo encontrar la fuente. – conradlee

18

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

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

También puede llamar a la item() method del objeto que desea convertir:

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

numpy sostiene que información en un mapeo expuesto como typeDict por lo que podría hacer algo como el 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 desea que el pyt real hon tipos en lugar de sus nombres, puede hacerlo ::

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

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

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

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

Cuestiones relacionadas