numpy.unique fornece saída incorreta para a lista de conjuntos

14

Eu tenho uma lista de conjuntos dados por,

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

Quando encontro os elementos exclusivos nesta lista usando números unique, recebo

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

Como pode ser visto, o resultado está errado, como {1}é repetido na saída.

Quando altero a ordem na entrada, tornando elementos semelhantes adjacentes, isso não acontece.

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

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

Por que isso ocorre? Ou há algo errado na maneira como eu fiz?

rashid
fonte
11
Não sei por que não funciona, mas suspeito que tenha a ver com o fato de que sets1.sort()não altera a ordem da lista. Acho que você precisa para criar uma função fpara classificar os conjuntos com base em qualquer critério que você deseja e, em seguida, passar sets1.sort(key=f)paranp.unique()
ATK7474

Respostas:

8

O que acontece aqui é que a np.uniquefunção é baseada na np._unique1dfunção do NumPy (consulte o código aqui ), que por si só usa o .sort()método

Agora, classificar uma lista de conjuntos que contêm apenas um número inteiro em cada conjunto não resultará em uma lista com cada conjunto ordenado pelo valor do número inteiro presente no conjunto. Então teremos (e não é isso 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

Agora, como você apontou, se a lista de conjuntos já estiver ordenada da maneira que você deseja, np.uniquefuncionará (já que você teria ordenado a lista anteriormente).

Uma solução específica (porém, lembre-se de que ela funcionará apenas para uma lista de conjuntos que cada um contém um único número inteiro) seria:

np.unique(sorted(sets, key=lambda x: next(iter(x))))
O príncipe Mestiço
fonte
-1

Isso porque set é do tipo unhashable

{1} is {1} # will give False

você pode usar python collections.Counterse puder converter o conjunto para tupla como abaixo

from collections import Counter
sets1 = [{1},{2},{1}]
Counter([tuple(a) for a in sets1])
Dev Khadka
fonte
iso teste não está relacionado ao hashability. A falta de capacidade de hash não é a razão pela qual np.unique () não funciona em conjuntos: de acordo com a resposta aceita, a falta de total ordenação é a razão. O uso de tupla () em conjuntos não garante a ordem de saída; portanto, dois conjuntos com os mesmos elementos podem ser convertidos incorretamente em tuplas diferentes.
Marius Gedminas