Aqui está o problema que encontro durante meu trabalho
O problema com a máscara quando não está definida
>>> a =np.arange(6,dtype=np.float64).reshape((2,3))
>>> a
array([[ 0., 1., 2.],
[ 3., 4., 5.]])
>>> am = np.ma.masked_array(a)
>>> am
masked_array(data =
[[ 0. 1. 2.]
[ 3. 4. 5.]],
mask =
False,
fill_value = 1e+20)
>>> am[0][1]=np.ma.masked
>>> am
masked_array(data =
[[ 0. 1. 2.]
[ 3. 4. 5.]],
mask =
False,
fill_value = 1e+20)
###--------- doesn't work----------------
>>> am[0,1]=np.ma.masked
>>> am
masked_array(data =
[[0.0 -- 2.0]
[3.0 4.0 5.0]],
mask =
[[False True False]
[False False False]],
fill_value = 1e+20)
###-------this way it works---------
>>> am[1][1]=np.ma.masked
>>> am
masked_array(data =
[[0.0 -- 2.0]
[3.0 -- 5.0]],
mask =
[[False True False]
[False True False]],
fill_value = 1e+20)
###--------now it surprisingly works again--
Linux 3.19.8-100.fc20.x86_64
Python 2.7.5
>>> np.__version__
'1.8.2'
Eu sei que meu sistema não está atualizado, mas perguntei a um amigo que tem
e ele confirma que o problema existe
Confirmado no mestre (1.12). Isso é parecido com o que # 5580 esperava consertar, mas como discutido lá, este caso específico não é possível consertar sem uma revisão do MaskedArray para remover np.nomask
.
Aqui está o problema: MaskedArrays às vezes armazenam a máscara como um array de booleanos e às vezes (se não houver valores mascarados) armazenam a máscara simplesmente como o valor False
(e np.nomask == False).
O problema é que ao fatiar um MaskedArray (e obter uma visualização), a máscara só pode ser "visualizada" se for atualmente um array de booleanos, mas não se for a constante "False". Portanto, a primeira vez que você tenta am[0][1] = ...
a máscara é a constante "False" e não pode ser exibida, portanto, não é atualizada. Na segunda vez que você tenta, a máscara está sendo armazenada como uma matriz de booleanos para que possa ser exibida e, portanto, seja atualizada.
Adicione isto à longa lista de bugs causados por este nomask
design, por exemplo, # 7588.
Cada vez que penso em nomask
, também penso naquela citação de Donald Knuth, "A otimização prematura é a raiz de todos os males."
Parece-me que nomask
não é exceção. O número de casos incomuns que encontramos por causa desse comportamento é muito grande e eles são mais difíceis de corrigir por causa disso.
Se fosse realmente tão produtivo saber se a máscara era trivial ou não, poderíamos com a mesma facilidade ter um método como has_mask
, que armazena seu resultado em cache.
Há algum interesse em remover nomask
uma vez?
Gostaria de alertar que também encontrei esse problema. Pode valer a pena adicionar uma nota na documentação sobre isso. A seguir, me sugere que modificar a máscara de uma visualização modificará a máscara do original.
Ao acessar uma fatia, a saída é uma matriz mascarada cujo atributo
data
é uma visualização dos dados originais e cuja máscara énomask
(se não houver entradas inválidas na matriz original) ou uma vista da fatia correspondente da máscara original. A visualização é necessária para garantir a propagação de qualquer modificação da máscara para o original.
Há algum interesse em remover o nomask de uma vez?
Talvez, também masked
. Isso provavelmente se resume a fazer algumas grandes mudanças nos arrays mascarados ou implementar uma classe totalmente nova. Pode valer a pena montar um NEP. Eu raramente uso arrays mascarados, então isso é algo melhor feito por pessoas que precisam da funcionalidade.
Comentários muito úteis
Cada vez que penso em
nomask
, também penso naquela citação de Donald Knuth, "A otimização prematura é a raiz de todos os males."Parece-me que
nomask
não é exceção. O número de casos incomuns que encontramos por causa desse comportamento é muito grande e eles são mais difíceis de corrigir por causa disso.Se fosse realmente tão produtivo saber se a máscara era trivial ou não, poderíamos com a mesma facilidade ter um método como
has_mask
, que armazena seu resultado em cache.Há algum interesse em remover
nomask
uma vez?