Use val.item()
para converter a maioria dos valores NumPy em um tipo Python nativo:
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'>
...
(Outro método é np.asscalar(val)
, no entanto, está obsoleto desde o NumPy 1.16).
Para os curiosos, crie uma tabela de conversões de escalares de array NumPy para o seu 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
Existem alguns tipos Numpy que não têm equivalente Python nativa em alguns sistemas, incluindo: clongdouble
, clongfloat
, complex192
, complex256
, float128
, longcomplex
, longdouble
e longfloat
. Eles precisam ser convertidos no equivalente NumPy mais próximo antes do uso .item()
.
np.str
não é do tipo Numpy, ou sejanp.str is str
, é apenas um apelido para um tipo Python padrão. Mesmo comnp.float
,np.int
,np.bool
,np.complex
, enp.object
. Os tipos Numpy têm um final_
, por exemplonp.str_
.np.float64(0).item()
e tambémnp.float(0).item()
. Em outras palavras, para os casos em que se sabe o que fazer, suporte o.item()
método mesmo se ele simplesmente retornar o mesmo valor. Dessa forma, eu poderia aplicar.item()
em escalares muito mais entorpecidos sem revestimento especial. No entanto, conceitos aparentemente paralelos diferem devido à implementação subjacente. Entendo perfeitamente por que isso foi feito. Mas é um aborrecimento para o usuário da biblioteca.me vi tendo um conjunto misto de tipos numpy e python padrão. como todos os tipos numpy derivam
numpy.generic
, veja como você pode converter tudo em tipos padrão python:fonte
np.asscalar()
método. Por quê? Provavelmente por nenhuma razão discernivelmente boa. Apesar de uma década de relativa estabilidade, a API do NumPy agora é um alvo móvel instável que exige manutenção constante de aplicativos a jusante. Pelo menos eles nos deixaram oitem()
método ... por enquanto.if isinstance(o, numpy.generic): return o.item() raise TypeError
e ela se transforma em uma resposta não obsoleta novamente: DSe você deseja converter (numpy.array OR numpy escalar OU tipo nativo OR numpy.darray) em tipo nativo, você pode simplesmente:
O tolist converterá seu escalar ou array em tipo nativo python. A função lambda padrão cuida do caso em que o valor já é nativo.
fonte
lambda: value
porque não queremos nenhuma entrada.getattr
+tolist
combo não é apenas universal, mas também vetorizado! (unlinke .item ())E se:
fonte
np.dtype('mint8')
para qualquer número inteiro positivom
. Não pode haver um mapeamento exaustivo. (Eu também não acredito que há uma função interna para fazer esta conversão para você Eu posso estar errado, mas eu não penso assim :).)>>> 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 você vê, nem todos os valores foram convertidos corretamente.>>> 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()
é uma abordagem mais geral para conseguir isso. Funciona em qualquer tipo primitivo e também em matrizes ou matrizes.Na verdade, eu não produz uma lista se chamado de tipos primitivos:
numpy == 1.15.2
fonte
Você também pode chamar o
item()
método do objeto que deseja converter:fonte
Eu acho que você pode escrever a função de conversão de tipo geral da seguinte maneira:
Isso significa que não há listas fixas e seu código será escalado com mais tipos.
fonte
numpy.ndarray
zero com elezeros()
e chamar andarrays
tolist()
função para converter em tipos nativos. Uma vez em tipos nativos, peço o tipo e o devolva.tolist()
é um fucntion dondarray
grep -r 'tolist' numpy
. (ainda em andamento, numpy é enorme!)numpy mantém essas informações em um mapeamento exposto
typeDict
para que você possa fazer algo como o abaixo:Se você quiser os tipos reais de python, em vez de seus nomes, poderá:
fonte
Desculpe chegar atrasado à parte, mas eu estava olhando para um problema de conversão apenas em
numpy.float64
Python comumfloat
. Eu vi três maneiras de fazer isso:npValue.item()
npValue.astype(float)
float(npValue)
Aqui estão os horários relevantes do IPython:
Parece que
float(npValue)
parece muito mais rápido.fonte
Minha abordagem é um pouco enérgica, mas parece ter um bom desempenho em todos os casos:
Uso:
fonte
Uma observação lateral sobre escalares de matriz para aqueles que não precisam de conversão automática e conhecem o tipo de valor numpy do valor:
Fonte
Portanto, na maioria dos casos, a conversão pode não ser necessária e o escalar da matriz pode ser usado diretamente. O efeito deve ser idêntico ao uso escalar do Python:
Mas se, por algum motivo, a conversão explícita for necessária, usar a função interna correspondente do Python é o caminho a percorrer. Como mostrado na outra resposta, também é mais rápido que o
item()
método escalar de array .fonte
Traduza o ndarray inteiro em vez de um objeto de dados da unidade:
No entanto, leva alguns minutos ao lidar com grandes quadros de dados. Também estou procurando uma solução mais eficiente. Espero uma resposta melhor.
fonte