Use val.item()
para convertir la mayoría de los valores de NumPy a un tipo nativo de Python:
import numpy as np
# for example, numpy.float32 -> python float
val = np.float32(0)
pyval = val.item()
print(type(pyval)) # <class 'float'>
# and similar...
type(np.float64(0).item()) # <class 'float'>
type(np.uint32(0).item()) # <class 'long'>
type(np.int16(0).item()) # <class 'int'>
type(np.cfloat(0).item()) # <class 'complex'>
type(np.datetime64(0, 'D').item()) # <class 'datetime.date'>
type(np.datetime64('2001-01-01 00:00:00').item()) # <class 'datetime.datetime'>
type(np.timedelta64(0, 'D').item()) # <class 'datetime.timedelta'>
...
(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 escalares 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 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 .item()
.
np.str
no es un tipo Numpy, es decirnp.str is str
, es solo un alias para un tipo Python estándar. Lo mismo connp.float
,np.int
,np.bool
,np.complex
, ynp.object
. Los tipos Numpy tienen un final_
, por ejemplonp.str_
.np.float64(0).item()
y tambiénnp.float(0).item()
. En otras palabras, para los casos en que se sabe qué hacer, respalde el.item()
método incluso si simplemente devuelve el mismo valor. De esa manera podría aplicar.item()
en escalares mucho más numpy sin carcasa especial. Tal como están las cosas, los conceptos aparentemente paralelos difieren debido a la implementación subyacente. Entiendo totalmente por qué se hizo esto. Pero es una molestia para el usuario de la biblioteca.Me encontré con un conjunto mixto de tipos numpy y python estándar. como se derivan todos los tipos numpy
numpy.generic
, así es como puede convertir todo a tipos estándar de python:fuente
np.asscalar()
método. ¿Por qué? Probablemente sin una razón apreciable. A pesar de una década de relativa estabilidad, la API NumPy es ahora un objetivo móvil inestable que exige un mantenimiento constante de las aplicaciones posteriores. Al menos nos dejaron elitem()
método ... por ahora.if isinstance(o, numpy.generic): return o.item() raise TypeError
y se convierte en una respuesta no obsoleta nuevamente: DSi desea convertir (numpy.array O numpy scalar O tipo nativo O numpy.darray) A tipo nativo, simplemente puede hacer:
tolist convertirá su escalar o matriz al tipo nativo de python. La función lambda predeterminada se encarga del caso donde el valor ya es nativo.
fuente
lambda: value
que no queremos ninguna entrada.getattr
¡+tolist
combo no solo es universal, sino incluso vectorizado! (unlinke .item ())Qué tal si:
fuente
np.dtype('mint8')
para cualquier entero positivom
. No puede haber un mapeo exhaustivo. (Tampoco creo que haya una función integrada para hacer esta conversión por usted. Podría estar equivocado, pero no lo creo :))>>> print([numpy.asscalar(x) for x in numpy.linspace(1.0, 0.0, 21)]) [1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.6499999999999999, 0.6, 0.55, 0.5, 0.44999999999999996, 0.3999999999999999, 0.35, 0.29999999999999993, 0.25, 0.19999999999999996, 0.1499999999999999, 0.09999999999999998, 0.04999999999999993, 0.0]
como puede ver, no todos los valores se convirtieron correctamente.>>> print([numpy.asscalar(round(x,2)) for x in numpy.linspace(1.0, 0.0, 21)]) [1.0, 0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6, 0.55, 0.5, 0.45, 0.4, 0.35, 0.3, 0.25, 0.2, 0.15, 0.1, 0.05, 0.0]
tolist()
Es un enfoque más general para lograr esto. Funciona en cualquier dtype primitivo y también en matrices o matrices.En realidad, no produce una lista si se llama desde tipos primitivos:
numpy == 1.15.2
fuente
También puede llamar al
item()
método del objeto que desea convertir:fuente
Creo que puedes escribir la función de conversión de tipo general de esta manera:
Esto significa que no hay listas fijas y su código se escalará con más tipos.
fuente
numpy.ndarray
1 con cerozeros()
y usar landarrays
tolist()
función para convertir a tipos nativos. Una vez en los tipos nativos, pido el tipo y lo devuelvo.tolist()
es una función delndarray
grep -r 'tolist' numpy
. (¡todavía en progreso, numpy es enorme!)numpy guarda esa información en un mapeo expuesto
typeDict
para que pueda hacer algo como lo siguiente ::Si desea los tipos de python reales en lugar de sus nombres, puede hacer ::
fuente
Lamento llegar tarde a la parte, pero estaba viendo un problema de conversión
numpy.float64
a Python normalfloat
solamente. Vi 3 formas de hacerlo:npValue.item()
npValue.astype(float)
float(npValue)
Aquí están los tiempos relevantes de IPython:
Parece que
float(npValue)
parece mucho más rápido.fuente
Mi enfoque es un poco contundente, pero parece ser bueno para todos los casos:
Uso:
fuente
Una nota al margen sobre los escalares de matriz para aquellos que no necesitan conversión automática y conocen el tipo numpy del valor:
Fuente
Por lo tanto, para la mayoría de los casos, la conversión podría no ser necesaria en absoluto, y el escalar de matriz podría usarse directamente. El efecto debe ser idéntico al uso del escalar Python:
Pero si, por alguna razón, se necesita la conversión explícita, usar la función incorporada de Python correspondiente es el camino a seguir. Como se muestra en la otra respuesta, también es más rápido que el
item()
método escalar de matriz .fuente
Traduzca el ndarray completo en lugar de un objeto de datos de unidad:
Sin embargo, lleva algunos minutos manejar grandes marcos de datos. También estoy buscando una solución más eficiente. Espero una mejor respuesta.
fuente