Problema ao filtrar o quadro de dados do resultado com uma or
condição. Desejo que meu resultado df
extraia todos os var
valores da coluna acima de 0,25 e abaixo de -0,25.
Essa lógica abaixo me fornece um valor de verdade ambíguo, mas funciona quando eu divido essa filtragem em duas operações separadas. O que esta acontecendo aqui? não sabe onde usar o sugerido a.empty(), a.bool(), a.item(),a.any() or a.all()
.
result = result[(result['var']>0.25) or (result['var']<-0.25)]
|
vez deor
abs(result['var'])>0.25
Respostas:
As instruções
or
eand
python requeremtruth
-values. Comopandas
estes são considerados ambíguos, você deve usar "bit a bit"|
(ou) ou&
(e):Elas estão sobrecarregadas para esse tipo de estrutura de dados para gerar a
or
(ouand
).Apenas para adicionar mais explicações a esta declaração:
A exceção é lançada quando você deseja obter o
bool
de apandas.Series
:O que você acertar era um lugar onde o operador implicitamente convertido os operandos
bool
(que usouor
mas também acontece paraand
,if
ewhile
):Além desses 4 declarações existem várias funções do Python que escondem algumas
bool
chamadas (comoany
,all
,filter
, ...), estes normalmente não são problemáticas compandas.Series
mas para ser completo eu queria mencionar estes.No seu caso, a exceção não é realmente útil, porque não menciona as alternativas corretas . Para
and
eor
você pode usar (se quiser comparações entre elementos):numpy.logical_or
:ou simplesmente o
|
operador:numpy.logical_and
:ou simplesmente o
&
operador:Se você estiver usando os operadores, certifique-se de definir seus parênteses corretamente devido a à precedência do operador .
Existem várias funções numpy lógicas que devem funcionar em
pandas.Series
.As alternativas mencionadas na exceção são mais adequadas se você a encontrar ao executar
if
ouwhile
. Em breve vou explicar cada um destes:Se você deseja verificar se sua série está vazia :
O Python normalmente interpreta o
len
g - ésimo de contêineres (comolist
,tuple
...) como valor de verdade se não tiver uma interpretação booleana explícita. Portanto, se você quiser a verificação do tipo python, poderá fazer:if x.size
ou emif not x.empty
vez deif x
.Se o seu
Series
contiver um e apenas um valor booleano:Se você deseja verificar o primeiro e único item da sua série (como
.bool()
mas funciona mesmo para conteúdos não booleanos):Se você deseja verificar se todo ou qualquer item não é zero, não está vazio ou não é falso:
fonte
and
,or
enot
em Python. Esses operadores usam diretamente o quebool
os operandos retornam. E de certa forma, o Pandas / NumPy sobrecarregou isso já para aumentar o valorValueError
porque considera o valor de verdade de uma estrutura de dados ambígua.Para lógica booleana, use
&
e|
.Para ver o que está acontecendo, você recebe uma coluna de booleanos para cada comparação, por exemplo
Quando você possui vários critérios, receberá várias colunas retornadas. É por isso que a lógica de junção é ambígua. Utilizando
and
ouor
tratando cada coluna separadamente, primeiro é necessário reduzir essa coluna para um único valor booleano. Por exemplo, para ver se algum valor ou todos os valores em cada uma das colunas são True.Uma maneira complicada de obter a mesma coisa é compactar todas essas colunas e executar a lógica apropriada.
Para mais detalhes, consulte Indexação booleana na documentação.
fonte
Bem, os pandas usam '&' '|' bit a bit e cada condição deve ser envolvida em um '()'
Por exemplo, seguindo trabalhos
Mas a mesma consulta sem colchetes adequados não
fonte
Ou, como alternativa, você pode usar o módulo Operador. Informações mais detalhadas estão aqui documentos Python
fonte
Esta excelente resposta explica muito bem o que está acontecendo e fornece uma solução. Gostaria de adicionar outra solução que possa ser adequada em casos semelhantes: usando o
query
método:Veja também http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query .
(Alguns testes com um dataframe em que estou trabalhando sugerem que esse método é um pouco mais lento do que usar os operadores bit a bit em séries de booleanos: 2 ms vs. 870 µs)
Um aviso : pelo menos uma situação em que isso não é direto é quando os nomes das colunas são expressões python. Eu tinha colunas chamado
WT_38hph_IP_2
,WT_38hph_input_2
elog2(WT_38hph_IP_2/WT_38hph_input_2)
e queria executar a seguinte consulta:"(log2(WT_38hph_IP_2/WT_38hph_input_2) > 1) and (WT_38hph_IP_2 > 20)"
Eu obtive a seguinte cascata de exceção:
KeyError: 'log2'
UndefinedVariableError: name 'log2' is not defined
ValueError: "log2" is not a supported function
Acho que isso aconteceu porque o analisador de consultas estava tentando criar algo com as duas primeiras colunas em vez de identificar a expressão com o nome da terceira coluna.
Uma possível solução alternativa é proposta aqui .
fonte
Encontrei o mesmo erro e fiquei paralisado com um dataframe do pyspark por alguns dias. Consegui resolvê-lo com êxito preenchendo valores n com 0, pois estava comparando valores inteiros de 2 campos.
fonte