データ分析の現場では、1つのセルの中に複数の値がリスト形式で格納されている場面に遭遇することが多々あります。
このような「1対多」の関係を持つデータを、通常のテーブル形式に変換するために欠かせないのがexplode関数です。
特にWeb APIから取得したJSON形式のデータや、アンケートの複数回答結果などを処理する際に、この関数は強力な力を発揮します。
本記事では、2026年時点での最新のPandas仕様に基づき、リスト展開を効率的に行うための実践的なテクニックを紹介します。
基本から応用まで、現場で即戦力となる知識を身に付けていきましょう。
explode関数の基本的な使い方
explode関数は、指定した列に含まれるリストや配列の要素を、それぞれ独立した行に展開する機能を持っています。
この関数を使用することで、複雑な階層構造を持つデータをフラットな形式に変換し、集計や分析が容易な状態に整えることができます。
まずは、最もシンプルな単一列の展開方法を確認してみましょう。
import pandas as pd
# サンプルデータの作成
df = pd.DataFrame({
'ID': [1, 2, 3],
'Category': [['A', 'B'], ['C'], ['D', 'E', 'F']]
})
# Category列を展開する
df_exploded = df.explode('Category')
print(df_exploded)
ID Category
0 1 A
0 1 B
1 2 C
2 3 D
2 3 E
2 3 F
実行結果を見ると、リスト内の各要素が新しい行として展開され、元のインデックス番号が保持されていることがわかります。
これにより、展開されたデータが元々どの行に属していたかを容易に追跡することが可能です。
複数列を同時に展開する方法
実務では、1つの行に対して複数の列にリストが格納されており、それらを同期させて展開したい場合があります。
Pandasのバージョン1.3以降では、explode関数にリスト形式で複数の列名を指定することが可能になりました。
この機能を利用することで、関連するデータをバラバラにすることなく、一度の操作で整形できます。
# 複数列にリストを持つデータの作成
df_multi = pd.DataFrame({
'ID': [1, 2],
'Tags': [['Tag1', 'Tag2'], ['Tag3', 'Tag4']],
'Values': [[10, 20], [30, 40]]
})
# Tags列とValues列を同時に展開
df_multi_exploded = df_multi.explode(['Tags', 'Values'])
print(df_multi_exploded)
ID Tags Values
0 1 Tag1 10
0 1 Tag2 20
1 2 Tag3 30
1 2 Tag4 40
このように、対応するリストの要素数が同じであれば、綺麗に同期して展開されます。
もしリストの長さが異なる列を同時に展開しようとするとエラーが発生するため、事前にデータの整合性を確認しておくことが重要です。
インデックスの再設定と重複の管理
explodeを適用した直後は、元のインデックスが重複した状態で残ります。
インデックスが重複していると、その後の結合(join)や集計操作で意図しない動作を引き起こす可能性があるため注意が必要です。
インデックスを連番にリセットしたい場合は、ignore_index=True引数を活用しましょう。
# インデックスをリセットしながら展開
df_reset = df.explode('Category', ignore_index=True)
print(df_reset)
ID Category
0 1 A
1 1 B
2 2 C
3 3 D
4 3 E
5 3 F
引数を使用せずに後からreset_index(drop=True)を実行しても同様の結果が得られますが、引数で指定する方がコードが簡潔になります。
空リストや欠損値(NaN)の挙動
データの中に空のリストや欠損値が含まれている場合、explodeがどのように処理を行うかを把握しておく必要があります。
デフォルトの挙動を理解しておくことで、データの消失や予期せぬ行の増加を防ぐことができます。
| データの状態 | explode後の結果 |
|---|---|
空リスト [] | 行は維持されるが、値は NaN になる |
欠損値 NaN | 行は維持され、値も NaN のまま |
| スカラー値(非リスト) | そのままの値で行が維持される |
空リストが含まれている場合、その行自体が消えてしまうのではなく、値がNaNとして1行分残るという点がポイントです。
もし展開後に不要な欠損値が生じた場合は、dropna()関数を組み合わせて除去する処理を検討してください。
応用:文字列のカンマ区切りを展開する
データソースによっては、リスト形式ではなく「値1,値2,値3」のように文字列としてデータが格納されていることがあります。
この場合、str.split()でリスト化してからexplodeを適用することで、効率的に展開できます。
# 文字列で連結されたデータ
df_str = pd.DataFrame({
'Project': ['Alpha', 'Beta'],
'Members': ['Alice,Bob', 'Charlie,David,Eve']
})
# カンマで分割してリスト化し、展開する
df_str['Members'] = df_str['Members'].str.split(',')
df_final = df_str.explode('Members')
print(df_final)
Project Members
0 Alpha Alice
0 Alpha Bob
1 Beta Charlie
1 Beta David
1 Beta Eve
このように、他のPandasメソッドと組み合わせることで、非構造的なデータも瞬時にクレンジングすることが可能です。
パフォーマンスに関する注意点
explode関数は非常に便利ですが、大量の行を持つデータセットに対して巨大なリストを展開する場合、メモリ消費量が急増します。
数百万行規模のデータで各セルに100個以上の要素が含まれているようなケースでは、処理速度が低下したり、メモリ不足(Out of Memory)が発生したりすることがあります。
そのような場合は、あらかじめ必要な列だけに絞り込んでから展開する、あるいはDaskなどの並列処理ライブラリを検討することが推奨されます。
通常の業務範囲であれば、Pandasの標準的なexplodeで十分に高速な処理が期待できるでしょう。
まとめ
Pandasのexplode関数は、複雑なリスト形式のデータを直感的なテーブル形式へ変換するための必須ツールです。
単一列の展開だけでなく、複数列の同期展開やインデックスの管理、さらには文字列分割との組み合わせなど、その応用範囲は多岐にわたります。
データの構造を正しく整理することは、その後の分析や機械学習モデルの精度向上に直結します。
今回紹介したテクニックを活用して、日々のデータ加工タスクをより効率的に、かつ正確に進めていきましょう。
