Numpy: Operador de atribuição de divisão gera erro, divisão separada e trabalho de atribuição

Criado em 9 fev. 2018  ·  3Comentários  ·  Fonte: numpy/numpy

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.

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

Todos 3 comentários

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.

Esta página foi útil?
0 / 5 - 0 avaliações