Pandasで2つのデータフレームに共通する行だけ残す・削除する方法


Pandasで2つのデータフレームを比較して処理を行う方法をまとめます。

例として以下のデータフレームを使用します。

import pandas as pd

df_2017 = pd.DataFrame({'種類':[1, 2, 3, 1, 3], 'サイズ': ["S", "S", "M", "L", "S"], '平均価格': [200, 120, 250, 300, 260]}) 
df_2020 = pd.DataFrame({'種類':[2, 2, 1, 1], 'サイズ': ["S", "M", "L", "M"], '平均価格': [130, 180, 340, 280]}) 

2017年のデータ

種類 サイズ 平均価格
0 1 S 200
1 2 S 120
2 3 M 250
3 1 L 300
4 3 S 190

2020年のデータ

種類 サイズ 平均価格
0 2 S 130
1 2 M 180
2 1 L 340
3 1 M 280

1. 共通する列を抽出する

2017年と2020年の両方に含まれる条件を抽出します。

df = pd.merge(df_2017,df_2020, suffixes = ["_2017", "_2020"], on=['種類', 'サイズ'])
#両方に共通の列名があるため、suffixesで添え字を指定する。デフォルトは_xと_y。

結果

種類 サイズ 平均価格_2017 平均価格_2020
0 2 S 120 130
1 1 L 300 340

2. 共通する列を削除する

2017年のデータから、2020年のデータにはない条件のみを抽出します。

df = pd.merge(df_2017,df_2020, on=['種類', 'サイズ'], how='outer', indicator=True)
#indicatorでどちらのデータフレームにあったかという情報を取得する
#mergeという列が追加され、both, left_only, right_onlyのいずれかが入る
df = df[df['_merge'] == 'left_only'].iloc[:,:3]

結果

種類 サイズ 平均価格_2017
0 1 S 200.0
2 3 M 250.0
3 3 S 190.0

以上です。
もっと楽なやり方があれば教えてください。