配列があるとします
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 秒、bincount
senderlein1d
のsetdiff1d
両方が 7.3 秒でした。スティーブンのCounter
は 10.5 秒と少し遅いだけです。後ろに続いているのは、110 秒の BurhanCounter.most_common
と 360 秒の DSM のCounter
減算です。
パフォーマンスのために並べ替えを使用しますが、パフォーマンスが許容範囲内であり、より明確で Pythonicに感じられるため、Steven の回答を受け入れます。
編集: Pandas ソリューションを発見しました。Pandas が利用できる場合、それは明確であり、適切に機能します。