配列があるとします
a = np.array([1, 2, 1, 3, 3, 3, 0])
どの要素aが重複しているか (つまり、一意でない値) を (効率的に、Python で) 見つけるにはどうすればよいですか? この場合、結果はarray([1, 3, 3])か、場合によってはarray([1, 3])効率的です。
うまくいくように見えるいくつかの方法を思いつきました:
マスキング
m = np.zeros_like(a, dtype=bool)
m[np.unique(a, return_index=True)[1]] = True
a[~m]
セット操作
a[~np.in1d(np.arange(len(a)), np.unique(a, return_index=True)[1], assume_unique=True)]
これはかわいいですが、おそらく違法です (a実際には一意ではないため):
np.setxor1d(a, np.unique(a), assume_unique=True)
ヒストグラム
u, i = np.unique(a, return_inverse=True)
u[np.bincount(i) > 1]
並べ替え
s = np.sort(a, axis=None)
s[:-1][s[1:] == s[:-1]]
パンダ
s = pd.Series(a)
s[s.duplicated()]
見逃したものはありますか?私は必ずしも numpy のみのソリューションを探しているわけではありませんが、numpy のデータ型で動作し、中規模のデータ セット (最大 1,000 万サイズ) で効率的でなければなりません。
結論
1,000 万サイズのデータ セットを使用したテスト (2.8GHz Xeon 上):
a = np.random.randint(10**7, size=10**7)
最速はソートで、1.1 秒です。怪しげなxor1d人は 2.6 秒で 2 位、続いてマスキングとパンダSeries.duplicatedが 3.1 秒、5.6 秒、bincountsenderlein1dのsetdiff1d両方が 7.3 秒でした。スティーブンのCounterは 10.5 秒と少し遅いだけです。後ろに続いているのは、110 秒の BurhanCounter.most_commonと 360 秒の DSM のCounter減算です。
パフォーマンスのために並べ替えを使用しますが、パフォーマンスが許容範囲内であり、より明確で Pythonicに感じられるため、Steven の回答を受け入れます。
編集: Pandas ソリューションを発見しました。Pandas が利用できる場合、それは明確であり、適切に機能します。