Desculpe se este é um problema conhecido, eu pesquisei, mas há tantos resultados ...
Isso funciona:
import numpy as np
a = np.array([1, 2, 3])
a = a / 4
Mas isso gera um erro:
import numpy as np
a = np.array([1, 2, 3])
a /= 4
Nomeadamente:
TypeError: No loop matching the specified signature and casting
was found for ufunc true_divide
Isso é surpreendente, pois eu esperaria que eles fizessem o mesmo.
Usando numpy versão 1.14.0.
Presumo que você esteja no Python 3. Esse é o comportamento esperado no Python 3. O resultado de a / 4
não será uma matriz de inteiros, mas uma matriz de ponto flutuante. Quando você simplesmente reatribui esse resultado com a linha a = a / 4
, tudo bem. Essencialmente, ele converte o código em a = np.true_divide(a, 4)
que cria uma nova matriz de ponto flutuante e reatribui o nome a
a ela.
Quando você tenta fazer uma atribuição in-loco, o true_divide
ufunc está sendo solicitado a produzir de volta no array a
inteiro existente: np.true_divide(a, 4, out=a)
. Não há implementação de true_divide
que recebe dois argumentos inteiros e produz outro inteiro, então você obtém a exceção.
Obrigado pela explicação clara, isso faz sentido. O seguinte me ajudou a entender a diferença:
>>> a = [1 ,2, 3]
>>> b = a
>>> id(a) == id(b)
True
>>> a += [4, 5, 6] # list object is changed, no new object created
>>> id(a) == id(b)
True
>>> a = a + [4, 5, 6] # new object created, and assigned to `a`
>>> id(a) == id(b)
False
Se bem entendi, o fato de nenhum novo objeto ser criado com +=
é a analogia com out=a
.
Uma maneira de contornar o problema é usar dtype=float
na criação do array.
Isso mesmo.
Comentários muito úteis
Presumo que você esteja no Python 3. Esse é o comportamento esperado no Python 3. O resultado de
a / 4
não será uma matriz de inteiros, mas uma matriz de ponto flutuante. Quando você simplesmente reatribui esse resultado com a linhaa = a / 4
, tudo bem. Essencialmente, ele converte o código ema = np.true_divide(a, 4)
que cria uma nova matriz de ponto flutuante e reatribui o nomea
a ela.Quando você tenta fazer uma atribuição in-loco, o
true_divide
ufunc está sendo solicitado a produzir de volta no arraya
inteiro existente:np.true_divide(a, 4, out=a)
. Não há implementação detrue_divide
que recebe dois argumentos inteiros e produz outro inteiro, então você obtém a exceção.