Deve modificar a docstring de acordo, gerar um erro significativo ou (de preferência) fazê-lo funcionar ocultando alguma lógica por baixo do capô.
Traceback:
In [11]: x = np.array([[True, True], [False, False]])
In [12]: np.diff(x)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-59225436601c> in <module>()
----> 1 np.diff(x)
/usr/lib/python3.6/site-packages/numpy/lib/function_base.py in diff(a, n, axis)
1924 return diff(a[slice1]-a[slice2], n-1, axis=axis)
1925 else:
-> 1926 return a[slice1]-a[slice2]
1927
1928
TypeError: numpy boolean subtract, the `-` operator, is deprecated, use the bitwise_xor, the `^` operator, or the logical_xor function instead.
In [13]: np.__version__
Out[13]: '1.13.0'
xref https://github.com/scikit-image/scikit-image/issues/2681
Parece uma solução fácil. A função diff
é puro Python e reside aqui:
https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py#L1835
Você provavelmente desejaria ramificar em a.dtype == bool
, e dada a observação sobre booleanos na docstring, use ^
(ou !=
) em vez de -
para manter compatibilidade com versões anteriores.
Parece-me que se -
está obsoleto, então diff
é perfeitamente razoável para não permitir também.
Bem - eu posso ver o argumento de pureza para não permitir, mas me parece que é razoável esperar que diff funcione em booleanos, e não é de se surpreender que a imagem do scikit estivesse fazendo isso. Então, eu teria pensado que uma filial em bool
era o melhor caminho.
Eu votaria em manter a funcionalidade. Se todos concordarmos, enviarei um patch ainda hoje ou amanhã.
PS Você poderia, por favor, apontar-me a discussão onde a justificativa para descontinuar -=
foi dada?
Se diff
está obsoleto em booleanos, então a docstring precisa ser atualizada para refletir isso. E provavelmente ainda desejaríamos ramificar em bool
para gerar mais um erro de contexto?
Parece-me que podemos querer um tipo np.uint1
que se comporte como um inteiro e não um booleano, no qual np.diff
e -
podem ser definidos.
Meu voto seria evitar que o usuário tivesse que parar e depurar um erro em np.diff(some_bools)
; primeiro - quebra a compatibilidade com versões anteriores e, segundo, o comportamento desejado é útil e claramente definido.
primeiro - quebra a compatibilidade com versões anteriores e, segundo, o comportamento desejado é útil e claramente definido.
Ambos os argumentos se aplicam a np.subtract
também, não é? Talvez essa discussão deva ser revisitada
Sim, eles fazem, e se você pensar instintivamente em diff
como uma implementação de subtract
então você provavelmente deseja um erro. Minha convicção é que as pessoas pensam em diff
de uma maneira ligeiramente diferente de subtract
, de modo que concordariam que subtrair bools não faz sentido, enquanto pegar diff
de bools faz - significando 'este valor é diferente do anterior'.
"este valor é diferente do anterior" soa como uma operação digna de seu próprio nome que generaliza para todos os dtypes, ao invés de soletrá-lo np.diff(x).astype(bool)
.
Talvez ufunc.pairwise(x, axis=...)
, implementado como ufunc(x[:-1], x[1:])
ignorando o argumento do eixo? Isso tornaria a função desejada np.not_equal.pairwise
.
Embora pairwise
possa implicar no comportamento que outer
já tem ...
Claro, isso também pode ser uma boa ideia - mas eu ainda argumentaria que seria mais gentil (praticidade supera pureza) perdoar essa maneira de pensar de bools e np.diff
.
O operador de subtração para booleanos está obsoleto há algum tempo, desde 1.9 eu acredito, a imagem scikit não tem prestado atenção. Prestar atenção também é uma boa ideia;) Acho que um nome diferente seria apropriado, xdiff ou algo parecido.
Dito isso, ter diff
handle booleanos para compatibilidade com versões anteriores é provavelmente uma boa ideia.
É um pouco injusto culpar a imagem do scikit aqui - não consigo ver nenhum aviso de suspensão de uso do numpy 1.12.1 e:
In [4]: np.diff([True, False])
Out[4]: array([ True], dtype=bool)
não consigo ver nenhum aviso de suspensão de uso para numpy 1.12.1 e
Isso porque, por padrão, DeprecationWarning
não é exibido. Adicione um import warnings; warnings.simplefilter('always')
e você o verá
In [1]: import warnings
In [2]: warnings.simplefilter('always')
In [3]: np.diff([True, False])
/home/charris/.local/lib/python2.7/site-packages/numpy/lib/function_base.py:1175: DeprecationWarning: numpy boolean subtract, the `-` operator, is deprecated, use the bitwise_xor, the `^` operator, or the logical_xor function instead.
return a[slice1]-a[slice2]
Out[3]: array([ True], dtype=bool)
In [4]: np.__version__
Out[4]: '1.10.4'
Outra coisa que devemos fazer é adicionar um teste para diff
usando um array booleano, seja para assert_raises
ou para validar o resultado.
Como a solução parece ser controversa (acho que estou com Matthew nisso, embora não me importe muito de qualquer maneira), enviei um e-mail para a lista para que todos tenham uma palavra a dizer.
Eu também sou do tipo pureza batida prática aqui, especialmente porque isso costumava funcionar. De alguma forma, como @ matthew-brett, há uma confusão "diff" é "diferença / difere" em minha mente, e certamente usei np.diff
como uma maneira rápida de encontrar lugares onde os valores mudaram.
ps @jaimefrio - Não vi nenhuma mensagem na lista de discussão (numerosa discussão).
1 para praticidade.
E definitivamente -1 para uma nova função. Se for útil, coloque-o em diff
. O namespace já é muito grande.
Sim, percebi que não consegui encontrar meu e-mail nos arquivos para vinculá-lo aqui. Mas há um e-mail na minha pasta enviada para [email protected] às 18:00 CET. Talvez o servidor esteja com problemas novamente? Ou esses problemas já foram corrigidos para sempre?
Endereço errado, mudou;) [email protected] .
Ah, isso explicaria ...
Aqui está um link para o e-mail, reenviado para o endereço correto, para referência futura:
https://mail.python.org/pipermail/numpy-discussion/2017-June/076877.html
Isso não parece nada bom - https://github.com/scipy/scipy/issues/7493 .
Alguém quer fazer um PR adicionando suporte para matrizes booleanas ao diff?
@charris eu faço. Estamos todos de acordo com isso?
@soupault acho que é o consenso.
Isso também se aplica a np.gradient
. Podemos consertar isso também? (pode dobrar em # 9411)
Digite ping na pergunta de @eric-wieser. Devemos corrigir np.gradient
também?
Pessoalmente, não vejo muito sentido em suportar gradientes de matrizes bool.
Comentários muito úteis
Bem - eu posso ver o argumento de pureza para não permitir, mas me parece que é razoável esperar que diff funcione em booleanos, e não é de se surpreender que a imagem do scikit estivesse fazendo isso. Então, eu teria pensado que uma filial em
bool
era o melhor caminho.