numpy.unique da un resultado incorrecto para la lista de conjuntos

14

Tengo una lista de conjuntos dados por,

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

Cuando encuentro los elementos únicos en esta lista usando numpy's unique, obtengo

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

Como se puede ver visto, el resultado es incorrecto como {1}se repite en la salida.

Cuando cambio el orden en la entrada haciendo elementos similares adyacentes, esto no sucede.

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

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

¿Por qué ocurre esto? ¿O hay algo mal en la forma en que lo he hecho?

rashid
fuente
1
No estoy seguro de por qué no funciona, pero sospecho que tiene que ver con el hecho de que sets1.sort()no cambia el orden de la lista. Creo que debe crear una función fpara ordenar los conjuntos según los criterios que desee, y luego pasar sets1.sort(key=f)anp.unique()
ATK7474

Respuestas:

8

Lo que sucede aquí es que la np.uniquefunción se basa en la np._unique1dfunción de NumPy (vea el código aquí ), que a su vez utiliza el .sort()método.

Ahora, ordenar una lista de conjuntos que contienen solo un número entero en cada conjunto no dará como resultado una lista con cada conjunto ordenado por el valor del número entero presente en el conjunto. Entonces tendremos (y eso no es lo que queremos):

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

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

Ahora, como ha señalado, si la lista de conjuntos ya está ordenada de la manera que desea, np.uniquefuncionará (ya que habría ordenado la lista de antemano).

Una solución específica (sin embargo, tenga en cuenta que solo funcionará para una lista de conjuntos que contienen un solo entero) sería:

np.unique(sorted(sets, key=lambda x: next(iter(x))))
El príncipe mestizo
fuente
-1

Esto se debe a que el conjunto es de tipo no compartible

{1} is {1} # will give False

puedes usar python collections.Countersi puedes convertir el conjunto a tupla como a continuación

from collections import Counter
sets1 = [{1},{2},{1}]
Counter([tuple(a) for a in sets1])
Dev Khadka
fuente
islas pruebas no están relacionadas con la capacidad de hashabilidad. La falta de hashability no es la razón por la que np.unique () no funciona en conjuntos: de acuerdo con la respuesta aceptada, la falta de ordenamiento total es esa razón. El uso de tuple () en conjuntos no garantiza el orden de salida, por lo que dos conjuntos con los mismos elementos podrían convertirse incorrectamente en tuplas diferentes.
Marius Gedminas