Comment vérifier si toutes les valeurs dans les colonnes d'une matrice numpy sont les mêmes?
je veux vérifier si toutes les valeurs dans les colonnes d'un tableau numpy/matrice sont les mêmes.
J'ai essayé d'utiliser reduce
ufuncequal
, mais il ne semble pas fonctionner dans tous les cas:
In [55]: a = np.array([[1,1,0],[1,-1,0],[1,0,0],[1,1,0]])
In [56]: a
Out[56]:
array([[ 1, 1, 0],
[ 1, -1, 0],
[ 1, 0, 0],
[ 1, 1, 0]])
In [57]: np.equal.reduce(a)
Out[57]: array([ True, False, True], dtype=bool)
In [58]: a = np.array([[1,1,0],[1,0,0],[1,0,0],[1,1,0]])
In [59]: a
Out[59]:
array([[1, 1, 0],
[1, 0, 0],
[1, 0, 0],
[1, 1, 0]])
In [60]: np.equal.reduce(a)
Out[60]: array([ True, True, True], dtype=bool)
Pourquoi la colonne du milieu, dans le second cas également évaluer True
, alors qu'il devrait être <!--4?
merci de votre aide!
2 réponses
In [45]: a
Out[45]:
array([[1, 1, 0],
[1, 0, 0],
[1, 0, 0],
[1, 1, 0]])
Comparer chaque valeur à la valeur correspondante dans la première ligne:
In [46]: a == a[0,:]
Out[46]:
array([[ True, True, True],
[ True, False, True],
[ True, False, True],
[ True, True, True]], dtype=bool)
Une colonne actions d'une valeur commune si toutes les valeurs de cette colonne sont remplies:
In [47]: np.all(a == a[0,:], axis = 0)
Out[47]: array([ True, False, True], dtype=bool)
Le problème np.equal.reduce
peut être vu en micro-analysant ce qui se passe quand il est appliqué à [1, 0, 0, 1]
:
In [49]: np.equal.reduce([1, 0, 0, 1])
Out[50]: True
Les deux premiers points, 1
et 0
sont testés pour l'égalité et le résultat est False
:
In [51]: np.equal.reduce([False, 0, 1])
Out[51]: True
Maintenant False
et 0
sont testés pour l'égalité et le résultat est True
:
In [52]: np.equal.reduce([True, 1])
Out[52]: True
Mais True
et 1 sont égaux, donc le résultat total est True
, qui n'est pas le résultat souhaité.
Le problème est que reduce
tente d'accumuler le résultat "localement", alors que nous voulons un test "global" comme np.all
.
étant donné l'explication géniale d'ubuntu, vous pouvez utiliser reduce
pour résoudre ton problème, mais vous devez l'appliquer à bitwise_and
et bitwise_or
plutôt que equal
. En conséquence, cela ne fonctionnera pas avec virgule flottante tableaux:
In [60]: np.bitwise_and.reduce(a) == a[0]
Out[60]: array([ True, False, True], dtype=bool)
In [61]: np.bitwise_and.reduce(b) == b[0]
Out[61]: array([ True, False, True], dtype=bool)
en gros, vous comparez les bits de chaque élément dans la colonne. Les bits identiques sont inchangés. Différents bits sont mis à zéro. De cette façon, tout nombre qui a un zéro au lieu d'un bit changera la valeur réduite. bitwise_and
ne sera pas de piège le cas où les bits sont introduits plutôt que supprimé:
In [62]: c = np.array([[1,0,0],[1,0,0],[1,0,0],[1,1,0]])
In [63]: c
Out[63]:
array([[1, 0, 0],
[1, 0, 0],
[1, 0, 0],
[1, 1, 0]])
In [64]: np.bitwise_and.reduce(c) == c[0]
Out[64]: array([ True, True, True], dtype=bool)
le second coumn est clairement erroné. Nous avons besoin d'utiliser bitwise_or
pour piéger les nouveaux bits:
In [66]: np.bitwise_or.reduce(c) == c[0]
Out[66]: array([ True, False, True], dtype=bool)
Réponse Finale
In [69]: np.logical_and(np.bitwise_or.reduce(a) == a[0], np.bitwise_and.reduce(a) == a[0])
Out[69]: array([ True, False, True], dtype=bool)
In [70]: np.logical_and(np.bitwise_or.reduce(b) == b[0], np.bitwise_and.reduce(b) == b[0])
Out[70]: array([ True, False, True], dtype=boo
In [71]: np.logical_and(np.bitwise_or.reduce(c) == c[0], np.bitwise_and.reduce(c) == c[0])
Out[71]: array([ True, False, True], dtype=bool)
cette méthode est plus restrictive et moins élégante que la suggestion d'ubunut d'utiliser all
, mais il a l'avantage de ne pas créer d'énormes temporaire des tableaux si votre entrée est énorme. Les tableaux temporaires ne devraient être aussi grands que la première rangée de votre matrice.
EDIT
sur la Base de ce Q / A et le bug que j'ai déposé avec numpy la solution fournie ne fonctionne que parce que votre tableau contient des zéros et des uns. Comme il arrive, le bitwise_and.reduce()
les opérations montrées ne peuvent retourner que zéro ou un parce que bitwise_and.identity
1
, pas -1
. Je suis en gardant cette réponse, dans l'espoir qu' numpy
est corrigé et la réponse devient valide.
Modifier
on dirait qu'il va y avoir en fait un changement à numpy bientôt. Certainement bitwise_and.identity
, et peut-être aussi un paramètre optionnel à réduire.
Modifier
bonnes nouvelles à tous. L'identité de np.bitwise_and
a été mis à -1
version 1.12.0
.