Pandasでデータフレームを合成する方法:実践的な例とテクニック

はじめに

データ分析において、複数のデータフレームを結合することはよく行われます。pandasライブラリは、縦方向・横方向のデータフレームの結合を行うためのconcat関数、キーによる結合を行うためのmerge関数、およびインデックスに基づく結合を行うためのjoin関数を提供しています。

この記事では、pandasライブラリを使って、データフレームを合成する方法を紹介します。具体的には、concat関数を使った縦方向の合成、横方向の合成、merge関数を使ったデータフレームの結合、およびjoin関数を使ったデータフレームの合成について解説します。さらに、データフレーム合成時の注意点についても触れます。

concat関数を使った縦方向の合成: 基本的な使い方と実例

concat関数を使うと、複数のデータフレームを縦方向に連結することができます。基本的な使い方は、以下のようになります。

import pandas as pd
# データフレームの生成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']})
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                    'B': ['B8', 'B9', 'B10', 'B11'],
                    'C': ['C8', 'C9', 'C10', 'C11'],
                    'D': ['D8', 'D9', 'D10', 'D11']})
# データフレームの連結
result = pd.concat([df1, df2, df3])
print(result)

この場合、df1、df2、df3の3つのデータフレームを縦方向に連結したデータフレームがresultに格納されます。連結する際には、引数に連結するデータフレームをリストで渡します。

次に、実際にデータフレームを連結する例を紹介します。

import pandas as pd
# データフレームの生成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']})
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                    'B': ['B8', 'B9', 'B10', 'B11'],
                    'C': ['C8', 'C9', 'C10', 'C11'],
                    'D': ['D8', 'D9', 'D10', 'D11']})
# データフレームの連結
result = pd.concat([df1, df2, df3])
print(result.head())

実行結果は以下のようになります。

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2
3  A3  B3  C3  D3
0  A4  B4  C4  D4

連結したデータフレームには、元のデータフレームの行番号がそのまま残っていることがわかります。これは、引数にignore_index=Trueを指定することで変更することができます。

import pandas as pd
# データフレームの生成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']})
df3 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']})
# データフレームの連結
result = pd.concat([df1, df2, df3], ignore_index=True)
print(result.head())

実行結果は以下のようになります。

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2
3  A3  B3  C3  D3
4  A4  B4  C4  D4

ignore_index=Trueを指定することで、行番号が連番に変更されたことがわかります。

concat関数を使った横方向の合成: オプションの設定方法と実例

concat関数を使うと、複数のデータフレームを横方向に連結することもできます。オプションによって、どのように連結するかを制御することができます。

以下は、基本的な使い方です。

import pandas as pd
# データフレームの生成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
df2 = pd.DataFrame({'E': ['E0', 'E1', 'E2', 'E3'],
                    'F': ['F0', 'F1', 'F2', 'F3'],
                    'G': ['G0', 'G1', 'G2', 'G3'],
                    'H': ['H0', 'H1', 'H2', 'H3']})
# データフレームの連結
result = pd.concat([df1, df2], axis=1)
print(result.head())

この場合、df1とdf2の2つのデータフレームを横方向に連結したデータフレームがresultに格納されます。連結する際には、引数に連結するデータフレームをリストで渡します。また、連結方向を制御するために、axis=1を指定します。

次に、実際にデータフレームを連結する例を紹介します。

import pandas as pd
# データフレームの生成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']})
df2 = pd.DataFrame({'E': ['E0', 'E1', 'E2','E3'],
                    'F': ['F0', 'F1', 'F2', 'F3'],
                    'G': ['G0', 'G1', 'G2', 'G3'],
                    'H': ['H0', 'H1', 'H2', 'H3']})
# データフレームの連結
result = pd.concat([df1, df2], axis=1)
print(result.head())

実行結果は以下のようになります。

    A   B   C   D   E   F   G   H
0  A0  B0  C0  D0  E0  F0  G0  H0
1  A1  B1  C1  D1  E1  F1  G1  H1
2  A2  B2  C2  D2  E2  F2  G2  H2
3  A3  B3  C3  D3  E3  F3  G3  H3

連結したデータフレームには、元のデータフレームの列がそのまま残っていることがわかります。

concat関数には、joinやkeysといったオプションがあります。詳細は、pandasの公式ドキュメントを参照してください。

merge関数を使ったデータフレームの結合: 結合方法の選択と実例

merge関数を使うと、2つのデータフレームをキーに基づいて結合することができます。結合方法には、内部結合、外部結合、左外部結合、右外部結合があります。

以下は、基本的な使い方です。

import pandas as pd
# データフレームの生成
left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                     'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})
# データフレームの結合
result = pd.merge(left, right, on='key')
print(result.head())

この場合、leftとrightの2つのデータフレームをkey列をキーにして結合したデータフレームがresultに格納されます。結合する際には、引数に結合するデータフレームを渡します。また、キーとなる列名は、onオプションで指定します。

実行結果は以下のようになります。

  key   A   B   C   D
0  K0  A0  B0  C0  D0
1  K1  A1  B1  C1  D1
2  K2  A2  B2  C2  D2
3  K3  A3  B3  C3  D3

左外部結合の場合、leftオプションに指定したデータフレームのすべての行が結果に含まれます。rightオプションに指定したデータフレームの中で、キーが一致する行があれば、それらの列が結果に含まれます。

右外部結合の場合、rightオプションに指定したデータフレームのすべての行が結果に含まれます。leftオプションに指定したデータフレームの中で、キーが一致する行があれば、それらの列が結果に含まれます。

merge関数には、howやsuffixesといったオプションがあります。詳細は、pandasの公式ドキュメントを参照してください。

join関数によるデータフレームの合成: 複数のデータフレームを結合する方法と実例

join関数を使うと、複数のデータフレームをキーに基づいて結合することができます。merge関数と同様に、結合方法には、内部結合、外部結合、左外部結合、右外部結合があります。

以下は、基本的な使い方です。

import pandas as pd
# データフレームの生成
left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                     'B': ['B0', 'B1', 'B2']},
                    index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C1', 'C2'],
                      'D': ['D0', 'D1', 'D2']},
                     index=['K0', 'K2', 'K3'])
top = pd.DataFrame({'E': ['E0', 'E1', 'E2'],
                    'F': ['F0', 'F1', 'F2']},
                   index=['K0', 'K1', 'K2'])
# データフレームの結合
result = left.join([right, top])
print(result)

この場合、left、right、topの3つのデータフレームを、インデックスをキーにして結合したデータフレームがresultに格納されます。結合する際には、引数に結合するデータフレームをリストで渡します。

次に、実際にデータフレームを結合する例を紹介します。

import pandas as pd
# データフレームの生成
left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                     'B': ['B0', 'B1', 'B2']},
                    index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C1', 'C2'],
                      'D': ['D0', 'D1', 'D2']},
                     index=['K0', 'K2', 'K3'])
top = pd.DataFrame({'E': ['E0', 'E1', 'E2'],
                    'F': ['F0', 'F1', 'F2']},
                   index=['K0', 'K1', 'K2'])
# データフレームの結合
result = left.join([right, top], how='outer')
print(result)

実行結果は以下のようになります。

      A    B    C    D    E    F
K0   A0   B0   C0   D0   E0   F0
K1   A1   B1  NaN  NaN   E1   F1
K2   A2   B2   C2   D2   E2   F2
K3  NaN  NaN   C1   D1  NaN  NaN

left、right、topの3つのデータフレームを、インデックスをキーにして結合したデータフレームがresultに格納されます。結合方法には、howオプションを指定することができます。この例では、outerを指定しています。outerを指定することで、すべてのデータを含む外部結合が行われます。

join関数には、onやhow、sortといったオプションがあります。詳細は、pandasの公式ドキュメントを参照してください。

データフレーム合成時の注意点: インデックスの扱いや欠損値処理について

データフレームを合成する際には、以下のような注意点があります。

  • データフレームを連結する場合、インデックスが重複するとエラーが発生します。
  • merge関数を使って結合する場合、データフレームのキーが重複すると、重複した行が複数回現れる可能性があります。
  • 欠損値が含まれる場合は、欠損値をどのように扱うかについて考慮する必要があります。

以下は、インデックスの重複に関する例です。

import pandas as pd
# データフレームの生成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                    'B': ['B0', 'B1', 'B2']},
                   index=['K0', 'K1', 'K2'])
df2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'],
                    'B': ['B3', 'B4', 'B5']},
                   index=['K2', 'K3', 'K4'])
# データフレームの連結
result = pd.concat([df1, df2])
print(result)

実行結果は以下のようになります。

     A   B
K0  A0  B0
K1  A1  B1
K2  A2  B2
K2  A3  B3
K3  A4  B4
K4  A5  B5

K2というインデックスが重複しているため、エラーが発生しませんが、K2に対応する行が2つ現れていることがわかります。

次に、欠損値の扱いに関する例を紹介します。

import pandas as pd
import numpy as np
# データフレームの生成
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                    'B': ['B0', 'B1', 'B2'],
                    'C': ['C0', np.nan, 'C2']})
df2 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                    'B': ['B0', 'B1', 'B2'],
                    'D': ['D0', 'D1', 'D2']})
# データフレームの結合
result = pd.merge(df1, df2, on=['A', 'B'])
print(result)

実行結果は以下のようになります。

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  NaN  D1
2  A2  B2  C2  D2

df1とdf2の2つのデータフレームをAとBの列をキーにして結合しています。df1のC列に欠損値が含まれていますが、結合後のデータフレームでは、欠損値がNaNとして扱われています。

まとめ

この記事では、pandasを使ってデータフレームを合成する方法について紹介しました。

まず、concat関数を使ってデータフレームを縦方向および横方向に連結する方法を紹介しました。その後、merge関数を使ってデータフレームを結合する方法と、join関数を使って複数のデータフレームをキーに基づいて結合する方法を紹介しました。

データフレームを合成する際には、インデックスの扱いや欠損値処理に注意する必要があります。インデックスが重複する場合には、エラーが発生する可能性があるため、注意が必要です。

今回紹介した合成方法は、pandasの基本的な機能です。pandasには、さまざまな合成方法がありますので、pandasの公式ドキュメントを参照することをおすすめします。

以上で、「pandasでデータフレームを合成する方法:実践的な例とテクニック」の記事を終わります。