こんにちは。投資エンジニアの三年坊主(@SannenBouzu)です。
今回は、pandasを使ったデータ分析を行いたい人の疑問に答えます。
pandasで重複行を削除したい。データ量が多いので、いきなり全部削除する前に対象となる重複行の一覧を確認したい。部分的に重複する行も対象にするにはどうすればいい?
大学の研究・自分の趣味・業務で、合わせて5年以上Pythonを使ってきた経験を生かして、データ分析ライブラリpandasで重複行を確認・削除する方法を紹介します。
- 用意したデータに重複があり、それを削除してからデータ分析を行いたい方
- データ量が多いので、重複行の一覧をまず確認したい方
- pandasで部分的に(一部のカラムだけ)重複する行も対象にして削除する方法を知りたい方
サンプルデータ【pandas.DataFrame】
サンプルデータを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import pandas as pd df = pd.DataFrame({ 'num':['1001', '1002', '1003'], 'dept': ['sales', 'dev', 'sales'], 'name1':['Adam', 'Brian', 'Carlos'], 'name2':['Smith', 'Taylor', 'Miller']} ) # 完全重複 (complete duplicate) df = df.append( {'num': '1002', 'dept': 'dev', 'name1': 'Brian', 'name2': 'Taylor'}, ignore_index=True ) # 部分重複 (partial duplicate) df = df.append( {'num': '1004', 'dept': 'dev', 'name1': 'Adam', 'name2': 'Smith'}, ignore_index=True ) |
duplicated()で(完全)重複行を確認する
DataFrameに対してduplicated()を使うと、重複する行について残すか残さないか決めるブール値のSeriesを作成できます。
引数keepはデフォルトでは”keep=’first'”で、重複する最初の行がFalseになります。
最初(first)の行が重複ではない(False)ということで、keepされるイメージですね。
keepは’first’, ‘last’, Falseのいずれかの値を取ります。
今回はFalseを指定=「重複した行全てをTrue」にして、削除する対象にしましょう。
1 2 3 4 5 6 7 8 9 10 | is_complete_duplicate = (df.duplicated(keep=False)) is_complete_duplicate # 出力結果 0 False 1 True 2 False 3 True 4 False dtype: bool |
ブール値のSeries、is_complete_duplicateを使って、完全に重複する行をdfから取り出しましょう。
1 2 3 4 5 6 7 | df_complete_duplicate = df[is_complete_duplicate] df_complete_duplicate # 出力結果 num dept name1 name2 1 1002 dev Brian Taylor 3 1002 dev Brian Taylor |
duplicated()で(部分)重複行を確認する
部分的に重複する行を確認したい場合は、dfからSeriesを指定してduplicated()を適用することができます。
例えば、name1とname2がどちらも同じ行を「重複」と考えたい場合は、以下のようにブール値のSeriesを作成できます。
1 2 3 4 5 6 7 8 9 10 11 | is_partial_duplicate = \ (df['name1'].duplicated(keep=False)) & (df['name2'].duplicated(keep=False)) is_partial_duplicate # 出力結果 0 True 1 True 2 False 3 True 4 True dtype: bool |
引数subsetを使って、指定した列が全て一致している行を「重複」と見なすこともできます。
1 2 3 4 5 6 7 8 9 10 11 | is_partial_duplicate2 = \ (df.duplicated(subset=['name1', 'name2'])) is_partial_duplicate2 # 出力結果 0 True 1 True 2 False 3 True 4 True dtype: bool |
部分的に重複する行を、以下のように確認してみましょう。
1 2 3 4 5 6 7 8 9 | df_partial_duplicate = df[is_partial_duplicate] df_partial_duplicate # 出力結果 num dept name1 name2 0 1001 sales Adam Smith 1 1002 dev Brian Taylor 3 1002 dev Brian Taylor 4 1004 dev Adam Smith |
pandasで重複した行を削除する
繰り返しになりますが、引数keepはデフォルトでは”keep=’first'”で、重複する最初の行がFalseになります。
1 2 3 4 5 6 7 8 9 10 | is_complete_duplicate_keep_first = (df.duplicated(keep='first')) is_complete_duplicate_keep_first # 出力結果 0 False 1 False 2 False 3 True 4 False dtype: bool |
論理否定演算子”~”で反転させると、重複する2回目以上の行だけがFalseになるので、dfから削除することができます。
1 2 3 4 5 6 7 8 | df[~is_complete_duplicate_keep_first] # 出力結果 num dept name1 name2 0 1001 sales Adam Smith 1 1002 dev Brian Taylor 2 1003 sales Carlos Miller 4 1004 dev Adam Smith |
drop_duplicates()で同じ結果を得ることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | df.drop_duplicates() # 出力結果 num dept name1 name2 0 1001 sales Adam Smith 1 1002 dev Brian Taylor 2 1003 sales Carlos Miller 4 1004 dev Adam Smith df[~is_complete_duplicate_keep_first].equals(df.drop_duplicates()) # 出力結果 True |
関連記事:こちらも読まれています
【2019年版】Pythonインストール・Mac編【長く安全に使える環境構築】
Pythonを快適に使いこなすMac環境【現役エンジニアおすすめはPro 13インチ】
アフィリエイトサイトの成果レポートを1クリックで集計【自動化で収益アップ?】