機械学習データ前処理:複数のデータセットを組み合わせる「結合(merge/join)」の種類と使い分け【Pandas入門】
はじめに:なぜ複数のデータを組み合わせる必要があるのか
機械学習のプロジェクトでは、分析対象となるデータが単一のファイルや表にすべて含まれているとは限りません。顧客情報、購買履歴、製品データ、プロモーションデータなど、異なる種類の情報が別々のデータセットとして存在することが一般的です。これらの異なるデータセットを組み合わせて分析することで、より深く、多角的な洞察を得ることが可能になります。
例えば、「特定の属性を持つ顧客がどのような製品を購入しやすいか」を分析するには、顧客の属性データと購買履歴データを組み合わせる必要があります。「プロモーションが製品の売上にどのように影響したか」を分析するには、製品売上データとプロモーション実施データを組み合わせることが求められます。
このように、複数のデータセットを共通の情報(キー)に基づいて結合する作業は、機械学習のためのデータ前処理において非常に重要なステップです。本記事では、Pythonのデータ分析ライブラリであるPandasを使用して、異なるデータセットを結合する基本的な方法と、いくつかの結合の種類について解説します。
Pandasにおけるデータ結合の基本:merge
関数
Pandasでは、主にmerge
関数を使って複数のデータフレーム(Pandasで扱う表形式のデータ構造)を結合します。merge
関数は、リレーショナルデータベースにおけるJOIN操作に似ています。共通する列(キー)に基づいて、2つのデータフレームを行方向に連結します。
基本的なmerge
関数の使い方は以下の通りです。
import pandas as pd
# 結合する2つのデータフレームを作成(例)
df1 = pd.DataFrame({
'key': ['A', 'B', 'C', 'D'],
'value1': [1, 2, 3, 4]
})
df2 = pd.DataFrame({
'key': ['B', 'D', 'E', 'F'],
'value2': [5, 6, 7, 8]
})
print("データフレーム1:")
print(df1)
print("\nデータフレーム2:")
print(df2)
# 結合の実行(デフォルトは内部結合)
merged_df = pd.merge(df1, df2, on='key')
print("\n結合後のデータフレーム(デフォルト:内部結合):")
print(merged_df)
上記の例では、df1
とdf2
という2つのデータフレームを作成し、共通する列である'key'
を基準に結合しています。on='key'
という引数で、どの列をキーとして結合するかを指定します。
デフォルトの結合方法は「内部結合(inner join)」と呼ばれ、両方のデータフレームに存在するキーに対応する行のみが結果として残ります。上記の例では、キー'B'
と'D'
が両方のデータフレームに存在するため、これらのキーに対応する行だけが結合後のデータフレームに含まれています。
結合の種類とその使い分け(how
引数)
merge
関数にはhow
という引数があり、これにより様々な種類の結合を指定できます。主な結合の種類とその概念、そしてどのような場合に使うのが適切かを解説します。
概念図としては、キーの集合AとBを考えたときに、how
引数はこれらの集合のどの部分を結果として含めるかを指定するものと考えると分かりやすいでしょう。
1. 内部結合 (how='inner'
)
- 概念: 両方のデータフレームに存在するキーに対応する行のみを結果に含めます。キーに対応する行が片方のデータフレームにしか存在しない場合、その行は破棄されます。
- 使いどころ: 両方の情報が必要な場合。例えば、顧客情報と購買履歴があり、「購入履歴がある顧客」の情報だけを分析したい場合などに用います。
- 例:
# 再度データフレームを定義
df1 = pd.DataFrame({
'key': ['A', 'B', 'C', 'D'],
'value1': [1, 2, 3, 4]
})
df2 = pd.DataFrame({
'key': ['B', 'D', 'E', 'F'],
'value2': [5, 6, 7, 8]
})
# 内部結合
inner_merged_df = pd.merge(df1, df2, on='key', how='inner')
print("内部結合の結果:")
print(inner_merged_df)
結果として、キー'B'
と'D'
に対応する行のみが含まれます。
2. 左外部結合 (how='left'
)
- 概念: 左側のデータフレーム(
merge
関数の最初の引数)に存在するすべてのキーに対応する行を結果に含めます。右側のデータフレームに対応するキーが存在しない場合は、その値はNaN
(欠損値)となります。 - 使いどころ: 特定のデータフレーム(左側)を基準に、別のデータフレーム(右側)の情報を付加したい場合。例えば、「すべての顧客情報に対し、購入履歴があればそれを付加したい。購入履歴がない顧客の情報も残したい」といった場合に用います。
- 例:
# 左外部結合
left_merged_df = pd.merge(df1, df2, on='key', how='left')
print("左外部結合の結果:")
print(left_merged_df)
結果として、df1
のキー'A'
, 'B'
, 'C'
, 'D'
がすべて含まれます。'A'
と'C'
はdf2
に存在しないため、value2
列はNaN
となります。
3. 右外部結合 (how='right'
)
- 概念: 右側のデータフレーム(
merge
関数の2番目の引数)に存在するすべてのキーに対応する行を結果に含めます。左側のデータフレームに対応するキーが存在しない場合は、その値はNaN
(欠損値)となります。 - 使いどころ: 左外部結合の逆で、右側のデータフレームを基準に情報を付加したい場合。例えば、「すべての製品情報に対し、売上データがあればそれを付加したい。まだ売上がない製品の情報も残したい」といった場合に用います。
- 例:
# 右外部結合
right_merged_df = pd.merge(df1, df2, on='key', how='right')
print("右外部結合の結果:")
print(right_merged_df)
結果として、df2
のキー'B'
, 'D'
, 'E'
, 'F'
がすべて含まれます。'E'
と'F'
はdf1
に存在しないため、value1
列はNaN
となります。
4. 外部結合 (how='outer'
)
- 概念: 左側または右側のデータフレームのいずれかに存在するすべてのキーに対応する行を結果に含めます。キーが片方にしか存在しない場合は、対応するもう片方のデータフレームの値は
NaN
となります。 - 使いどころ: どちらかのデータフレームに存在するすべての情報を網羅したい場合。例えば、「すべての顧客情報とすべての製品情報を組み合わせ、それぞれの関連データを付加したい」といった、データ全体の関係性を確認したい場合に用いることがあります。ただし、欠損値が多く発生しやすい点に注意が必要です。
- 例:
# 外部結合
outer_merged_df = pd.merge(df1, df2, on='key', how='outer')
print("外部結合の結果:")
print(outer_merged_df)
結果として、df1
とdf2
のすべてのキー('A'
, 'B'
, 'C'
, 'D'
, 'E'
, 'F'
)が結果に含まれます。対応する値が存在しない箇所はNaN
となります。
複数のキーで結合する場合
複数の列を組み合わせて結合のキーとしたい場合もあります。例えば、「顧客ID」と「注文日」のペアでデータセットを結合するなどです。この場合は、on
引数に列名のリストを指定します。
df_sales = pd.DataFrame({
'CustomerID': [101, 102, 101, 103, 102],
'OrderDate': ['2023-01-15', '2023-01-16', '2023-01-20', '2023-01-18', '2023-01-25'],
'Amount': [1000, 2500, 1500, 3000, 2000]
})
df_promotion = pd.DataFrame({
'CustomerID': [101, 102, 104, 101],
'OrderDate': ['2023-01-15', '2023-01-16', '2023-01-22', '2023-02-01'],
'DiscountApplied': [True, True, False, False]
})
print("売上データ:")
print(df_sales)
print("\nプロモーションデータ:")
print(df_promotion)
# CustomerIDとOrderDateのペアをキーとして内部結合
merged_sales_promo = pd.merge(df_sales, df_promotion, on=['CustomerID', 'OrderDate'], how='inner')
print("\nCustomerIDとOrderDateをキーとした内部結合結果:")
print(merged_sales_promo)
この例では、CustomerID
とOrderDate
の両方が一致する行のみが結合されています。
結合における注意点
- キーのデータ型: 結合のキーとして使用する列のデータ型は、両方のデータフレームで一致している必要があります。文字列(object型)と数値(int/float型)などが混在していると、意図した通りに結合できない場合があります。必要に応じてデータ型変換を行いましょう。
- キーの名前: 結合する列の名前が異なる場合は、
left_on
とright_on
引数を使ってそれぞれ指定する必要があります。 - 重複キー: キー列に重複する値がある場合、結合結果の行数は増加します。例えば、データフレームAのキー
'X'
に2行、データフレームBのキー'X'
に3行がある場合、内部結合すると'X'
に対応する行は 2 × 3 = 6行になります。これは意図しない結果を招く可能性があるため、必要に応じて結合前に重複を確認・処理することも検討しましょう。 - 欠損値の発生: 外部結合や左右外部結合では、キーに対応する値が存在しない場合に
NaN
が発生します。結合後のデータフレームで欠損値が発生していないか確認し、必要に応じて補完などの欠損値処理を行う必要があります。
まとめ
本記事では、機械学習のためのデータ前処理における重要なステップである、複数のデータフレームの結合について解説しました。Pandasのmerge
関数を用いれば、共通するキーに基づいて異なるデータセットを効率的に組み合わせることができます。
- 内部結合 (
inner
): 両方に存在するキーで結合 - 左外部結合 (
left
): 左側のデータフレームを基準に結合 - 右外部結合 (
right
): 右側のデータフレームを基準に結合 - 外部結合 (
outer
): どちらかに存在するキーで結合
分析の目的に応じて適切な結合方法を選択することが重要です。また、キーのデータ型や重複の有無、結合後の欠損値などにも注意を払いながら作業を進めることが、正確なデータ前処理を行う上で不可欠です。
データ結合は、単なるデータの連結ではなく、異なる情報源から得られたデータを統合し、分析の幅を広げるための強力な手法です。ここで学んだ知識を活かして、ご自身のデータ分析や機械学習のプロジェクトにお役立てください。