Voici le problème que j'ai rencontré pendant mon travail
Le problème avec le masque lorsqu'il n'est pas défini
>>> 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'
Je sais que mon système n'est pas à jour mais j'ai demandé à un ami qui a
et il confirme que le problème existe
Confirmé en master (1.12). C'est comme ce que # 5580 espérait corriger, mais comme indiqué ici, ce cas particulier n'est pas possible de résoudre sans une refonte de MaskedArray pour supprimer np.nomask
.
Voici le problème: MaskedArrays stocke parfois le masque comme un tableau de booléens, et parfois (s'il n'y a pas de valeurs masquées) stocke le masque simplement sous la valeur False
(et np.nomask == False).
Le problème est que lors du découpage d'un MaskedArray (et de l'obtention d'une vue), le masque ne peut être "visualisé" que s'il s'agit actuellement d'un tableau de booléens, mais pas s'il s'agit de la constante "False". Donc, la première fois que vous essayez am[0][1] = ...
le masque est la constante "False" et ne peut pas être visualisé, il n'est donc pas mis à jour. La deuxième fois que vous essayez, le masque est stocké sous la forme d'un tableau de booléens afin qu'il puisse être visualisé, et donc mis à jour.
Ajoutez ceci à la longue liste de bogues causés par ce design nomask
, par exemple # 7588.
Chaque fois que je pense à nomask
, je pense aussi à cette citation de Donald Knuth: «L'optimisation prématurée est la racine de tout mal».
Il me semble que nomask
ne fait pas exception. Le nombre de cas inhabituels rencontrés à cause de ce comportement est assez important et ils sont rendus plus difficiles à corriger à cause de cela.
Si c'était vraiment une chose tellement productive de savoir si le masque était trivial ou non, nous pourrions tout aussi bien avoir une méthode comme has_mask
, qui met en cache son résultat.
Y a-t-il un intérêt à passer à la suppression totale de nomask
?
Je voudrais souligner que j'ai également rencontré ce problème. Il pourrait être intéressant d'ajouter une note dans la documentation à ce sujet. Ce qui suit me suggère que la modification du masque d'une vue modifiera le masque de l'original.
Lors de l'accès à une tranche, la sortie est un tableau masqué dont l'attribut
data
est une vue des données d'origine, et dont le masque est soitnomask
(s'il n'y avait aucune entrée invalide dans le tableau d'origine) ou une vue de la tranche correspondante du masque d'origine. La vue est nécessaire pour assurer la propagation de toute modification du masque à l'original.
Y a-t-il un intérêt à passer à la suppression pure et simple de nomask?
Peut-être aussi masked
. Cela revient probablement soit à apporter de gros changements aux tableaux masqués, soit à implémenter une nouvelle classe. Cela vaudrait peut-être la peine de créer un NEP. J'utilise rarement des tableaux masqués, c'est donc quelque chose de mieux fait par les personnes qui ont besoin de la fonctionnalité.
Commentaire le plus utile
Chaque fois que je pense à
nomask
, je pense aussi à cette citation de Donald Knuth: «L'optimisation prématurée est la racine de tout mal».Il me semble que
nomask
ne fait pas exception. Le nombre de cas inhabituels rencontrés à cause de ce comportement est assez important et ils sont rendus plus difficiles à corriger à cause de cela.Si c'était vraiment une chose tellement productive de savoir si le masque était trivial ou non, nous pourrions tout aussi bien avoir une méthode comme
has_mask
, qui met en cache son résultat.Y a-t-il un intérêt à passer à la suppression totale de
nomask
?