Acabei de descobrir um bug lógico no meu código que estava causando todos os tipos de problemas. Eu estava inadvertidamente fazendo um AND bit a bit em vez de um AND lógico .
Eu mudei o código de:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]
PARA:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]
Para minha surpresa, recebi a mensagem de erro bastante enigmática:
ValueError: o valor verdadeiro de uma matriz com mais de um elemento é ambíguo. Use a.any () ou a.all ()
Por que um erro semelhante não foi emitido quando uso uma operação bit a bit - e como faço para corrigir isso?
Respostas:
r
é uma matriz numpy (rec). O mesmor["dt"] >= startdate
acontece com uma matriz (booleana). Para matrizes numpy, a&
operação retorna o elemento-e das duas matrizes booleanas.Os desenvolvedores do NumPy consideraram que não havia uma maneira comum de avaliar uma matriz no contexto booleano: isso poderia significar
True
se algum elemento éTrue
, ouTrue
se todos os elementos sãoTrue
ouTrue
se a matriz tem comprimento diferente de zero, apenas para citar três possibilidades.Como usuários diferentes podem ter necessidades diferentes e suposições diferentes, os desenvolvedores do NumPy se recusaram a adivinhar e decidiram aumentar um ValueError sempre que alguém tenta avaliar uma matriz no contexto booleano. A aplicação
and
a duas matrizes numpy faz com que as duas matrizes sejam avaliadas no contexto booleano (chamando__bool__
no Python3 ou__nonzero__
no Python2).O seu código original
parece correto. No entanto, se você quiser
and
, em vez dea and b
usar(a-b).any()
ou(a-b).all()
.fonte
np.all
enp.any
são capazes de curto-circuito, o argumento passado para ele é avaliado antesnp.all
ounp.any
tem uma chance de curto-circuito. Para fazer melhor, atualmente, você teria que escrever um código C / Cython especializado semelhante a este .Eu tive o mesmo problema (ou seja, indexação com várias condições, aqui estão os dados em um determinado período). O
(a-b).any()
ou(a-b).all()
parece não estar funcionando, pelo menos para mim.Como alternativa, encontrei outra solução que funciona perfeitamente para a funcionalidade desejada ( o valor verdadeiro de uma matriz com mais de um elemento é ambíguo ao tentar indexar uma matriz ).
Em vez de usar o código sugerido acima, simplesmente usar a
numpy.logical_and(a,b)
funcionaria. Aqui você pode reescrever o código comofonte
O motivo da exceção é que
and
chama implicitamentebool
. Primeiro no operando esquerdo e (se o operando esquerdo estiverTrue
), depois no operando direito. Entãox and y
é equivalente abool(x) and bool(y)
.No entanto, o
bool
on anumpy.ndarray
(se contiver mais de um elemento) lançará a exceção que você viu:A
bool()
chamada está em implícitoand
, mas também emif
,while
,or
, então qualquer um dos exemplos a seguir também falhará:Existem mais funções e instruções no Python que ocultam
bool
chamadas, por exemplo,2 < x < 10
é apenas outra maneira de escrever2 < x and x < 10
. E oand
chamarábool
:bool(2 < x) and bool(x < 10)
.O equivalente a elementos
and
seria para anp.logical_and
função, da mesma forma que você poderia usarnp.logical_or
como equivalente paraor
.Para matrizes booleanas - e comparações como
<
,<=
,==
,!=
,>=
e>
no NumPy matrizes retornam matrizes Numpy boolean - você também pode usar os elementos-wise bit a bit funções (e operadores):np.bitwise_and
(&
operador)e
bitwise_or
(|
operador):Uma lista completa de funções lógicas e binárias pode ser encontrada na documentação do NumPy:
fonte
se você trabalha com o
pandas
que resolveu o problema para mim foi que estava tentando fazer cálculos quando tinha valores de NA, a solução era executar:df = df.dropna()
E depois disso o cálculo falhou.
fonte
Essa mensagem de erro digitada também mostra enquanto
if-statement
é feita uma comparação onde há uma matriz e, por exemplo, um bool ou int. Veja por exemplo:Esta cláusula tem conjunto de dados como array e bool é euhm a "porta aberta" ...
True
ouFalse
.Caso a função esteja agrupada em um,
try-statement
você receberáexcept Exception as error:
a mensagem sem o tipo de erro:fonte
tente isso => numpy.array (r) ou numpy.array (sua variável) seguido pelo comando para comparar o que você desejar.
fonte