Pandas concat()でDataFrame・Seriesを自由自在に連結!データ結合の基本 🔗


 

Pandasで複数のデータセットを扱う際、それらを一つにまとめる「連結(Concatenation)」操作は非常によく使われます。例えば、月ごとの売上データを年間のデータとして縦に結合したり、同じ顧客IDを持つ異なる情報源のデータを横に並べたりする場面です。Pandasの**concat()関数**は、DataFrameSeriesを柔軟に連結するための強力なツールです。

この記事では、concat()の基本的な使い方から、縦方向・横方向への連結、そしてインデックスの扱い方まで、具体的なコード例を交えながら詳しく解説します。


 

pd.concat()とは?なぜ使うのか? 🤔

 

concat()関数は、引数として与えられた複数のPandasオブジェクト(DataFrameまたはSeries)を、指定された軸(行または列)に沿って結合します。

 

concat()を使うメリット

 

  • 柔軟な連結: DataFrameだけでなくSeriesも連結でき、縦方向(行)にも横方向(列)にも結合できます。

  • シンプルな構文: 複数のオブジェクトをリストで渡すだけで簡単に連結できます。

  • インデックス制御: 連結後のインデックスをどのように扱うかを細かく制御できます。


 

concat()の基本的な使い方 ✨

 

concat()関数は、連結したいPandasオブジェクトのリストを最初の引数に取ります。

 

1. 縦方向への連結 (axis=0):行を追加 📈

 

デフォルトではaxis=0(または'index')が指定され、オブジェクトは縦方向(行方向)に連結されます。これは、同じ構造を持つデータフレームを積み重ねるイメージです。

Python
 
import pandas as pd

df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})

print("--- df1 ---")
print(df1)
print("\n--- df2 ---")
print(df2)

# df1とdf2を縦方向に連結
result_rows = pd.concat([df1, df2])
print("\n--- 縦方向への連結 (df1の下にdf2を追加) ---")
print(result_rows)
# 出力例:
#     A   B
# 0  A0  B0
# 1  A1  B1
# 0  A2  B2
# 1  A3  B3

 

インデックスの扱い:ignore_indexkeys

 

上記の例では、元のインデックスがそのまま引き継がれているため、重複が発生しています。これを解決するためのオプションがいくつかあります。

  • ignore_index=True: 連結後に新しい連番のインデックスを振り直します。重複を避けたい場合に便利です。

    Python
     
    import pandas as pd
    
    df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
    df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
    
    result_ignore_index = pd.concat([df1, df2], ignore_index=True)
    print("\n--- ignore_index=True でインデックスを振り直し ---")
    print(result_ignore_index)
    # 出力例:
    #    A   B
    # 0  A0  B0
    # 1  A1  B1
    # 2  A2  B2
    # 3  A3  B3
    
  • keys: 各DataFrameの識別のための階層的なインデックス(MultiIndex)を追加します。

    Python
     
    import pandas as pd
    
    df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
    df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
    
    result_keys = pd.concat([df1, df2], keys=['df1_data', 'df2_data'])
    print("\n--- keys で階層インデックスを追加 ---")
    print(result_keys)
    # 出力例:
    #              A   B
    # df1_data 0  A0  B0
    #          1  A1  B1
    # df2_data 0  A2  B2
    #          1  A3  B3
    

 

2. 横方向への連結 (axis=1):列を追加 ➡️

 

axis=1(または'columns')を指定すると、オブジェクトは横方向(列方向)に連結されます。これは、共通のインデックスを持つデータフレームに新しい列を追加するイメージです。

Python
 
import pandas as pd

df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'C': ['C0', 'C1'], 'D': ['D0', 'D1']})

print("--- df1 ---")
print(df1)
print("\n--- df2 ---")
print(df2)

# df1とdf2を横方向に連結 (インデックスが一致する行が結合される)
result_cols = pd.concat([df1, df2], axis=1)
print("\n--- 横方向への連結 (インデックスが一致する行を結合) ---")
print(result_cols)
# 出力例:
#     A   B   C   D
# 0  A0  B0  C0  D0
# 1  A1  B1  C1  D1

 

インデックスの不一致とjoin引数

 

横方向への連結でインデックスが一致しない場合、NaN(欠損値)が発生します。この挙動はjoin引数で制御できます。

  • join='outer' (デフォルト): すべてのインデックスを含めます(外部結合のような挙動)。

  • join='inner': 両方のオブジェクトに共通するインデックスのみを含めます(内部結合のような挙動)。

Python
 
import pandas as pd

df3 = pd.DataFrame({'A': [1, 2]}, index=['X', 'Y'])
df4 = pd.DataFrame({'B': [3, 4]}, index=['Y', 'Z'])

print("--- df3 ---")
print(df3)
print("\n--- df4 ---")
print(df4)

# 横方向へ外部結合 (デフォルト)
result_outer_join = pd.concat([df3, df4], axis=1, join='outer')
print("\n--- 横方向 + outer join (デフォルト) ---")
print(result_outer_join)
# 出力例:
#      A    B
# X  1.0  NaN
# Y  2.0  3.0
# Z  NaN  4.0

# 横方向へ内部結合
result_inner_join = pd.concat([df3, df4], axis=1, join='inner')
print("\n--- 横方向 + inner join ---")
print(result_inner_join)
# 出力例:
#    A  B
# Y  2  3

 

3. Seriesの連結

 

SeriesDataFrameと同様にconcat()で連結できます。

Python
 
import pandas as pd

s1 = pd.Series([1, 2], name='Val1')
s2 = pd.Series([3, 4], name='Val2')

# Seriesを縦に連結
result_s_v = pd.concat([s1, s2])
print("\n--- Seriesを縦に連結 ---")
print(result_s_v)

# Seriesを横に連結 (DataFrameになる)
result_s_h = pd.concat([s1, s2], axis=1)
print("\n--- Seriesを横に連結 (DataFrame化) ---")
print(result_s_h)
# 出力例:
#    Val1  Val2
# 0     1     3
# 1     2     4

 

merge() vs concat():使い分けのヒント 💡

 

concat()と似た機能にmerge()がありますが、これらは目的が異なります。

  • concat(): データを「積み重ねる」または「並べる」イメージで、同じインデックスや列名を持つことが保証されていなくても結合できます。インデックスや列の順序が重要で、共通の「キー」がなくても結合したい場合に適しています。

  • merge(): 共通の「キー(列)」に基づいて「結合」するイメージで、リレーショナルデータベースのJOIN操作に近いです。異なるDataFrame間の論理的な関連性に基づいてデータを結合したい場合に適しています。

機能concat()merge()
結合方向縦 (axis=0) または 横 (axis=1)常に横方向
結合基準インデックス/位置、または列名(axis=1の場合)共通の(キー)
柔軟性複数のオブジェクトを単に連結共通キーに基づいて行をマッチングし結合
用途– 同じスキーマのデータを積み重ねる<br>- 共通インデックスの列を並べる– IDなどのキーを持つデータを結合する<br>- 異なる情報源を統合する

 

まとめ

 

Pandasのconcat()関数は、DataFrameSeriesを柔軟に連結するための非常に便利なツールです。

  • 縦方向の連結: pd.concat([df1, df2]) (デフォルト axis=0)

  • 横方向の連結: pd.concat([df1, df2], axis=1)

  • インデックスの振り直し: ignore_index=True

  • 階層インデックスの付与: keys=['name1', 'name2']

  • インデックス不一致時の結合: join='inner' または join='outer'

これらのconcat()の機能を使いこなすことで、複数のデータセットを効率的に統合し、分析の次のステップへと進めることができるでしょう。ぜひ様々なデータを試して、この連結テクニックをマスターしてください!