numpy.unique donne une sortie incorrecte pour la liste des ensembles

14

J'ai une liste d'ensembles donnés par,

sets1 = [{1},{2},{1}]

Lorsque je trouve les éléments uniques de cette liste à l'aide de numpy's unique, j'obtiens

np.unique(sets1)
Out[18]: array([{1}, {2}, {1}], dtype=object)

Comme on peut le voir, le résultat est incorrect, comme cela {1}est répété dans la sortie.

Lorsque je change l'ordre dans l'entrée en faisant des éléments similaires adjacents, cela ne se produit pas.

sets2 = [{1},{1},{2}]

np.unique(sets2)
Out[21]: array([{1}, {2}], dtype=object)

Pourquoi cela se produit-il? Ou y a-t-il quelque chose qui ne va pas dans ma façon de faire?

rashid
la source
1
Je ne sais pas pourquoi cela ne fonctionne pas, mais je soupçonne que cela a à voir avec le fait que sets1.sort()cela ne change pas l'ordre de la liste. Je pense que vous devez créer une fonction fpour trier les ensembles en fonction des critères que vous souhaitez, puis passer sets1.sort(key=f)ànp.unique()
ATK7474

Réponses:

8

Ce qui se passe ici, c'est que la np.uniquefonction est basée sur la np._unique1dfonction de NumPy (voir le code ici ), qui lui-même utilise la .sort()méthode.

Désormais, le tri d'une liste d'ensembles qui ne contiennent qu'un seul entier dans chaque ensemble n'entraînera pas une liste avec chaque ensemble ordonné par la valeur de l'entier présent dans l'ensemble. Nous aurons donc (et ce n'est pas ce que nous voulons):

sets = [{1},{2},{1}]
sets.sort()
print(sets)

# > [{1},{2},{1}]
# ie. the list has not been "sorted" like we want it to

Maintenant, comme vous l'avez souligné, si la liste des ensembles est déjà ordonnée comme vous le souhaitez, np.uniquecela fonctionnera (puisque vous auriez trié la liste au préalable).

Une solution spécifique (cependant, sachez que cela ne fonctionnera que pour une liste d'ensembles contenant chacun un seul entier) serait alors:

np.unique(sorted(sets, key=lambda x: next(iter(x))))
Le Prince de sang mêlé
la source
-1

En effet, l'ensemble est de type non partageable

{1} is {1} # will give False

vous pouvez utiliser python collections.Countersi vous pouvez convertir l'ensemble en tuple comme ci-dessous

from collections import Counter
sets1 = [{1},{2},{1}]
Counter([tuple(a) for a in sets1])
Dev Khadka
la source
isles tests ne sont pas liés à la capacité de hachage. Le manque d'habilité n'est pas la raison pour laquelle np.unique () ne fonctionne pas sur les décors: selon la réponse acceptée, le manque de commande totale est cette raison. L'utilisation de tuple () sur les ensembles ne garantit pas l'ordre de sortie, donc deux ensembles avec les mêmes éléments peuvent être incorrectement convertis en différents tuples.
Marius Gedminas