Określanie zduplikowanych wartości w tablicy

Załóżmy, że mam tablicę

a = np.array([1, 2, 1, 3, 3, 3, 0])

Jak mogę (wydajnie, Pythonicznie) znaleźć elementya są duplikatami (tzn. wartościami nieunikalnymi)? W tym przypadku wynik byłby takiarray([1, 3, 3]) lub ewentualniearray([1, 3]) jeśli jest wydajny.

Wymyśliłem kilka metod, które wydają się działać:

Maskowanie
m = np.zeros_like(a, dtype=bool)
m[np.unique(a, return_index=True)[1]] = True
a[~m]
Ustaw operacje
a[~np.in1d(np.arange(len(a)), np.unique(a, return_index=True)[1], assume_unique=True)]

Ten jest słodki, ale prawdopodobnie nielegalny (jaka w rzeczywistości nie jest wyjątkowy):

np.setxor1d(a, np.unique(a), assume_unique=True)
Histogramy
u, i = np.unique(a, return_inverse=True)
u[np.bincount(i) > 1]
Sortowanie
s = np.sort(a, axis=None)
s[:-1][s[1:] == s[:-1]]
Pandy
s = pd.Series(a)
s[s.duplicated()]

Czy jest coś, co przegapiłem? Niekoniecznie szukam rozwiązania zawierającego tylko numpy, ale musi on pracować z typami danych numpy i być wydajny na średnich zestawach danych (do 10 milionów).

Wnioski

Testowanie z zestawem danych o rozmiarze 10 milionów (na Xeonie 2,8 GHz):

a = np.random.randint(10**7, size=10**7)

Najszybszy jest sortowanie na poziomie 1,1. Wątpliwyxor1d jest drugi na 2.6, po którym następuje maskowanie i PandySeries.duplicated w 3.1sbincount na 5,6s, iin1d i nadawcysetdiff1d oba na 7,3. StevenaCounter jest tylko trochę wolniejszy, 10,5s; w tyle za BurhanemCounter.most_common w 110s i DSMCounter odejmowanie w 360s.

Będę używał sortowania dla wydajności, ale akceptuję odpowiedź Stevena, ponieważ wydajność jest akceptowalna i toczuje jaśniejszy i bardziej Pythonic.

Edytuj: odkrył rozwiązanie Pandas. Jeśli Pandy są dostępne, jest jasne i działa dobrze.

questionAnswers(8)

yourAnswerToTheQuestion