numpy.unique podaje błędne dane wyjściowe dla listy zestawów

14

Mam listę zestawów podaną przez,

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

Kiedy znajduję unikalne elementy na tej liście za pomocą numpy unique, otrzymuję

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

Jak można zobaczyć, wynik jest błędny, jak {1}powtarza się na wyjściu.

Kiedy zmieniam kolejność na wejściu, tworząc podobne elementy obok siebie, tak się nie dzieje.

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

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

Dlaczego tak się dzieje? Czy może coś jest nie tak z moim postępowaniem?

pochopny
źródło
1
Nie jestem pewien, dlaczego to nie działa, ale podejrzewam, że ma to związek z faktem, że sets1.sort()nie zmienia kolejności listy. Myślę, że musisz utworzyć funkcję fdo sortowania zestawów na podstawie dowolnych kryteriów, a następnie przejść sets1.sort(key=f)donp.unique()
ATK7474,

Odpowiedzi:

8

To, co się tutaj dzieje, polega na tym, że np.uniquefunkcja jest oparta na np._unique1dfunkcji z NumPy (patrz kod tutaj ), która sama używa tej .sort()metody.

Teraz sortowanie listy zestawów zawierających tylko jedną liczbę całkowitą w każdym zestawie nie spowoduje utworzenia listy z każdym zestawem uporządkowanym według wartości liczby całkowitej znajdującej się w zestawie. Więc będziemy mieli (i nie tego chcemy):

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

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

Teraz, jak wskazałeś, jeśli lista zestawów jest już uporządkowana w pożądany sposób, np.uniquebędzie działać (ponieważ wcześniej posortowałeś listę).

Jedno konkretne rozwiązanie (należy jednak pamiętać, że będzie działać tylko dla listy zestawów, z których każdy zawiera jedną liczbę całkowitą), to:

np.unique(sorted(sets, key=lambda x: next(iter(x))))
Książę Półkrwi
źródło
-1

Dzieje się tak, ponieważ zestaw jest typem nieukrywalnym

{1} is {1} # will give False

możesz użyć Pythona, collections.Counterjeśli możesz przekonwertować zestaw na krotkę jak poniżej

from collections import Counter
sets1 = [{1},{2},{1}]
Counter([tuple(a) for a in sets1])
Dev Khadka
źródło
istestowanie nie ma związku z hashowaniem. Brak mieszalności nie jest przyczyną, że np.unique () nie działa na zestawach: zgodnie z przyjętą odpowiedzią przyczyną jest brak całkowitego uporządkowania. Użycie tuple () na zestawach nie gwarantuje uporządkowania danych wyjściowych, więc dwa zestawy z tymi samymi elementami mogą niepoprawnie zostać przekonwertowane na różne krotki.
Marius Gedminas