Numpy: Erreurs de diffusion avec des masques booléens multidimensionnels

Créé le 3 avr. 2019  ·  3Commentaires  ·  Source: numpy/numpy

En tentant d'indexer un tableau 2D de forme [N, M] avec deux masques booléens 1D, les formes N et M, certaines combinaisons de Vrai et Faux conduisent à une erreur de diffusion (notamment lorsque l'un est tout faux). Je ne sais pas si ce comportement est attendu, mais il semble très surprenant et indésirable.

Dans l'exemple ci-dessous, les erreurs x[[False, True, True], [True, True, True]] , tandis que x[[False, True, True], True] et x[[False, True, True]] ont le comportement attendu.

Exemple de code de reproduction :

import numpy as np
from itertools import product

x = np.zeros((3,3))
mask_1d = [*product([True, False], repeat=3)]

for row_mask, col_mask in product(mask_1d, mask_1d):
    try:
        x[row_mask, col_mask]
    except IndexError as e:
        print(row_mask, col_mask)
        print(e)

Message d'erreur:

     (True, True, True) (True, True, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,) 
(True, True, True) (True, False, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,) 
(True, True, True) (False, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,) 
(True, True, True) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (0,) 
(True, True, False) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,) 
(True, True, False) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 
(True, False, True) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,) 
(True, False, True) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 
(False, True, True) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (3,) 
(False, True, True) (False, False, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 
(False, False, False) (True, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (3,) 
(False, False, False) (True, True, False)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (2,) 
(False, False, False) (True, False, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (2,) 
(False, False, False) (False, True, True)
shape mismatch: indexing arrays could not be broadcast together with shapes (0,) (2,)

Informations sur la version Numpy/Python :

1.16.2 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:22:34) 
[GCC 7.3.0]

Commentaire le plus utile

Avec les tableaux booléens, le code suppose que vous essayez d'indexer une seule dimension ou tous les éléments en même temps - le choix étant malheureusement quelque peu deviné d'une manière qui permet de supprimer un seul True . C'est-à-dire qu'il transforme votre row_mask, col_mask en un tableau booléen (2,3), puis constate qu'il ne peut pas indexer le tableau (3,3).

Une partie du problème est que les tuples et les listes sont traités comme équivalents, ce dont nous essayons de nous éloigner. Finalement, vous géreriez l'index du tableau booléen en vous assurant que le masque était une double liste.

Pour l'instant, cependant, je crains que la seule solution soit de faire x[row_mask][:, col_mask] .

cc @eric-wieser, qui a travaillé pour déprécier le "traiter le tuple comme une liste" pour les opérations d'indexation.

ps Le plus ennuyeux je trouve cette différence:

x = np.arange(9).reshape(3, 3)
# x[[False, True, True], True]
# array([[3, 4, 5],
#        [6, 7, 8]])
x[[False, True, True], False]
# IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 

Tous les 3 commentaires

Avec les tableaux booléens, le code suppose que vous essayez d'indexer une seule dimension ou tous les éléments en même temps - le choix étant malheureusement quelque peu deviné d'une manière qui permet de supprimer un seul True . C'est-à-dire qu'il transforme votre row_mask, col_mask en un tableau booléen (2,3), puis constate qu'il ne peut pas indexer le tableau (3,3).

Une partie du problème est que les tuples et les listes sont traités comme équivalents, ce dont nous essayons de nous éloigner. Finalement, vous géreriez l'index du tableau booléen en vous assurant que le masque était une double liste.

Pour l'instant, cependant, je crains que la seule solution soit de faire x[row_mask][:, col_mask] .

cc @eric-wieser, qui a travaillé pour déprécier le "traiter le tuple comme une liste" pour les opérations d'indexation.

ps Le plus ennuyeux je trouve cette différence:

x = np.arange(9).reshape(3, 3)
# x[[False, True, True], True]
# array([[3, 4, 5],
#        [6, 7, 8]])
x[[False, True, True], False]
# IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (2,) (0,) 

Oui, x[row_mask][:, col_mask] est ce que j'ai fini par faire. Merci pour l'explication, je suis content que ce soit quelque chose qui soit examiné.

Je pense que arr[np.ix_(index)] est ce que vous voulez/attendez ici, ou en d'autres termes sur la logique d'indexation externe comme dans NEP 21 : https://github.com/numpy/numpy/blob/master/doc/neps /nep-0021-indexation-avancée.rst

Peut-être que cela sera repris un jour. Le NEP dit également qu'au moins pour l'indexation actuelle, plusieurs indices booléens devraient simplement être dépréciés (je pense que l'autorisation de ce cas d'utilisation spécifique peut encore avoir été contestée - c'est cohérent, mais peut ne pas avoir beaucoup de cas d'utilisation et être assez déroutant dans en tout cas).

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

thouis picture thouis  ·  4Commentaires

'
Pezhvuk picture Pezhvuk  ·  4Commentaires

perezpaya picture perezpaya  ·  4Commentaires

marcocaccin picture marcocaccin  ·  4Commentaires

manuels picture manuels  ·  3Commentaires