膨大で整理されていないデータセットには、切り口によって重複するデータも存在しえます。
Pandasではそうした重複している行を抽出したり、除去することができます。今回はその方法について紹介します。
使用するデータ
Kaggleから、FIFA22のMLS(Major League Soccer)所属の選手データセットを使用します。
https://www.kaggle.com/drhythm/fifa-22-mls-player-ratings
import pandas as pd
df = pd.read_csv("C:/Project/FIFA 22 MLS PLAYER RATINGS.csv")
df
重複行の抽出
重複行を抽出するにはduplicated()を用います。
df.duplicated()
>>
0 False
1 False
2 False
3 False
4 False
...
619 False
620 False
621 False
622 False
623 False
Length: 624, dtype: bool
重複している行はTrue、重複していない行はFalseとしたSeriesが返されます。
何も指定していない場合は、全ての列で重複していればTrueとなります。今回はそのようなデータはないため、Falseばかりになっています。
特定の列をSeriesとして抽出した場合にも同様に用いることができます。
df['POS'].duplicated()
>>
0 False
1 True
2 False
3 False
4 False
...
619 True
620 True
621 True
622 True
623 True
Name: POS, Length: 624, dtype: bool
重複している行をデータフレームで抽出したい場合は、以下のようにします。
df[df.duplicated()]
今回はなんと1件もありませんでした、、(みなさんのデータで試してみてください)
重複していない行だけを抽出する場合は以下のようにします。
df[~df.duplicated()]
重複判定対象の列を指定する
特定列の値が重複しているかで判定したい場合は、引数にsubsetを指定します。
df.duplicated(subset='POS')
>>
0 False
1 True
2 False
3 False
4 False
...
619 True
620 True
621 True
622 True
623 True
Name: POS, Length: 624, dtype: bool
複数列で重複を判定したい場合は、配列で指定します。
df.duplicated(subset=['POS', 'DRI'])
>>
0 False
1 True
2 False
3 False
4 False
...
619 False
620 True
621 True
622 True
623 True
Length: 624, dtype: bool
この条件で重複行を抽出してみます。
df[df.duplicated(subset=['POS', 'DRI'])]
624行中381行が重複しているようです。意外と重複してるなという感じですが、これは’POS’と’DRI’の値が同じ行が他に1つでもある行が残るためです。このとき重複している行のうち指定した行は重複していないとみなされ、Falseとなります(後述)。
抽出時に残す行の指定
重複する全ての行をTrueとすると、重複を取り除こうとしたときに全ての行が排除され、その値の行は1つも残らなくなってしまいます。それを避けるため、重複した行のうち1つを残すことができます。
残す行は引数keepで指定し、デフォルトはfirstです。firstは、重複する行のうち最初に出現した行をfalseとして残します(それ以外はTrue)。lastを指定すると、最後の行が残ります。
参考に元のデータフレームを再掲します。
#最初が残る
df.duplicated(subset=['POS', 'DRI'])
>>
0 False
1 True
2 False
3 False
4 False
...
619 False
620 True
621 True
622 True
623 True
Length: 624, dtype: bool
#最後が残る
df.duplicated(subset=['POS', 'DRI'], keep='last')
>>
0 True
1 True
2 True
3 True
4 True
...
619 False
620 False
621 False
622 False
623 False
Length: 624, dtype: bool
重複がある行を1つも残したくない場合はkeep=Falseとします。
df.duplicated(subset=['POS', 'DRI'], keep=False)
>>
0 True
1 True
2 True
3 True
4 True
...
619 False
620 True
621 True
622 True
623 True
Length: 624, dtype: bool
重複行の削除
上で紹介した~を用いた方法を用いて重複行を削除することができますが、drop_duplicates()を用いることもできます。
df[~df.duplicated()]
df.drop_duplicates()
drop_duplicates()はduplicated()と同様にsubsetやkeepといった引数を使うことができます。重複行を削除した例は以下のようになります。
#'POS'の重複が無いように抽出
df.drop_duplicates(subset='POS')
Seriesに対しても適用することができます。
df['POS'].drop_duplicates()
>>
0 RB
2 ST
3 CB
4 GK
6 CM
8 LB
10 RW
12 CDM
18 RM
20 LM
47 CAM
68 LW
81 LWB
131 RWB
313 SS
Name: POS, dtype: object
Pythonでデータサイエンスするなら
Pythonでデータサイエンスをするなら、以下の書籍がおすすめです。Pandas、matplotlib、Numpy、scikit-learnといったデータサイエンスに必要なライブラリを、体系立てて一通り学ぶことができます。
ややお値段高めですが、これ1冊で十分という内容・ボリュームなので、損はしないと思います^^
初学者の方にはこちらもオススメです^^
まとめ
Pandasで重複行を抽出/削除する方法を紹介しました。データ整形の際に役立ててください^^
ではでは👋