Numpy: Controle "Média da fatia vazia" RunTimeWarning com np.errstate

Criado em 8 mar. 2018  ·  7Comentários  ·  Fonte: numpy/numpy

Como já existe um mecanismo em numpy para gerenciar avisos para entradas possivelmente anômalas, parece estranho que ele não funcione para todos os avisos. Por exemplo, nanmean gera um aviso se receber uma fatia de todos os nan e, aparentemente, a única maneira de silenciá-lo é capturá-lo com o mecanismo de avisos do python. np.errstate , apesar de alegar lidar com erros de divisão por zero, não:

Python 3.6.2 
In [1]: import numpy as np
In [2]: np.__version__
Out[2]: '1.13.1'

In [3]: allnan = np.array([np.nan, np.nan])
In [4]: with np.errstate(divide='ignore', invalid='ignore'):
   ...:     print(np.nanmean(allnan))
   ...:     
/Users/jonathanshor/anaconda2/envs/Python3/bin/ipython:2: RuntimeWarning: Mean of empty slice
  if __name__ == '__main__':
nan

Eu sugeriria que isso poderia cair no caso de divisão, mas inválido parece plausível também.

Comentários muito úteis

Isso precisaria de algo mais do que um

class AllNanAxisWarning(RuntimeWarning):
    pass

E então substituir esses RuntimeWarnings no restante de https://github.com/numpy/numpy/blob/v1.15.0/numpy/lib/nanfunctions.py ? Porque se isso for tudo o que for necessário, posso enviar um PR.

Todos 7 comentários

np.errstate() controla o mecanismo de exceção de ponto flutuante de ufuncs apenas, não avisos / erros em funções numpy em geral. ufuncs requerem um mecanismo separado porque são basicamente invólucros em torno de funções C que são chamadas em cada um dos elementos dos arrays individualmente. np.errstate() não tem a intenção de unir a manipulação de todos os avisos e exceções do numpy. Espera-se que você use o módulo warnings para capturar esses RuntimeWarnings que são explicitamente gerados.

Isso é o que estou achando decepcionante, pois apresenta aos usuários finais como eu uma situação estranha de ter que quebrar operações aparentemente semelhantes em dados potencialmente NaN contendo dados individuais np.errstate() e warnings.catch_warnings() , ou jogue a "pia da cozinha" neles e embrulhe tudo em ambos.

Parece uma escolha de design (que é o que estou propondo mudar). Vejo agora que nanmean chama _divide_by_count , que na verdade se vale do mecanismo exato que eu gostaria de usar: with np.errstate(invalid='ignore', divide='ignore'): , ocultando qualquer aviso encontrado.
nanmean então faz seu próprio teste (redundante) para verificar se há div por zero, e gera seu próprio aviso estranho.

A causa raiz do aviso é uma divisão por zero. Não seria mais fácil simplesmente permitir que esse aviso passasse?
Se evitar confusão na mensagem de Aviso for importante, sugiro que "Média de fatia vazia" em uma fatia contendo NaNs é provavelmente mais confusa do que um erro div por zero, ou pelo menos era para mim.

O mecanismo warnings é o mecanismo padrão básico. errstate() entra para os ufuncs, pois eles são pequenos excêntricos especiais. Se warnings estivesse por perto quando numpy adicionou pela primeira vez o mecanismo ufunc para exceções de ponto flutuante, provavelmente o teríamos apenas usado.

Você deve usar warnings para capturar / silenciar Warning s que são gerados explicitamente. Você também deve se sentir à vontade para usar warnings para silenciar Warning s que são ativados por padrão por ufuncs; é por isso que tornamos 'warn' o modo padrão para os FPEs sobre os quais queríamos fazer barulho. Você também deve se sentir à vontade para usar np.errstate() quando realmente precisar apenas trabalhar com os FPEs de ufuncs, como _divide_by_count() .

A mensagem deste Warning realmente não é muito útil. Tenho vagas lembranças de que pode ter sido um resquício de quando essa função foi implementada de maneira diferente e foi mantida assim formulada para que os filtros existentes ainda a detectassem. Eu seria a favor de reformulá-lo para dizer que uma entrada all-NaN foi passada (embora você tenha que ser cuidadoso na frase para não ficar confuso quando axis= recebeu algo e é apenas uma única linha ou qualquer que seja). Eu também seria a favor da subclasse de RuntimeWarning para dar um aviso mais facilmente capturado para este e os outros nanfunctions .

Hmmm, OK, eu posso realmente usar warnings para pegar tudo. Eu entendo o que você está dizendo sobre as razões históricas dos ufuncs terem seu tratamento especial.

É improvável que eu mesmo tenha tempo para enviar um PR sobre isso tão cedo, especialmente um que contenha uma subclasse robusta da classe de advertência. Parece que a etiqueta aqui é deixar o assunto em aberto, mas feche-o se eu estiver enganado!

Eu também seria a favor da subclasse de RuntimeWarning para fornecer um aviso mais facilmente capturado para esta e outras nanofunções.

Essa é uma excelente sugestão. Talvez "AllNanAxisWarning" ou algo semelhante.

Como o consenso que alcançamos sobre a ação a ser executada é diferente do título e da discussão inicial, provavelmente seria melhor encerrar este problema e começar um novo com a solicitação de consenso. É mais provável que você obtenha um esforço voluntário dessa forma.

Isso precisaria de algo mais do que um

class AllNanAxisWarning(RuntimeWarning):
    pass

E então substituir esses RuntimeWarnings no restante de https://github.com/numpy/numpy/blob/v1.15.0/numpy/lib/nanfunctions.py ? Porque se isso for tudo o que for necessário, posso enviar um PR.

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