PythonでExcelの1つのセルに入った複数の値を行に分ける手順|explodeで1件ずつ数える
Excelの表で「請求,配送」のように1つのセルにまとめて入れた値を、Pythonのpandasのstr.splitとexplodeで1行ずつに分け、件数を数える手順を解説します。空白や空欄でずれる原因も、架空の表で試して紹介します。
目次
この記事でわかること
- 1つのセルに入った複数の値を、1つずつの行に分ける方法(str.splitとexplode)
- 分けた後に、値ごとの件数を数える方法
- 区切りの後の空白や空欄で、数がずれる理由
- 行の番号の扱いと、元の形に戻す方法
問い合わせの表の「分類」の列に「請求,配送」のように複数の値をまとめて入れていて、分類ごとの件数を数えるたびに、手で行を増やしていませんか。この記事では、1つのセルの値を区切って1件ずつの行にし、そのまま数える手順を紹介します。
参考にしたのは、pandas 3.1.0のDataFrame.explode・Series.explode・Series.str.splitの説明で、2026年10月31日に原文を確かめました。表は、説明用に作った架空の問い合わせの記録です。
先に結論: 区切ってリストにしてから、explodeで行に広げる
str.splitで「請求,配送」を「請求」と「配送」のリストにし、explodeでリストの中身を1つずつの行に広げます。 区切りの後に空白があるなら、最後にstr.stripで取り除きます。
| 受付番号 | 元の分類 | 分けた後の行 |
|---|---|---|
| 1 | 請求,配送 | 請求・配送の2行 |
| 2 | 配送 | 配送の1行 |
| 3 | 返品, 請求 | 返品・請求の2行 |
| 4 | (空欄) | 空の1行 |
explodeのしくみ
pandasの資料では、explodeを、リストのような値の要素を1つずつ行に変え、行の番号を写す操作だと説明しています。ほかの列の値は、分けた行のそれぞれに同じものが入ります。
リストではない値は、そのまま残ります。そのため、「請求,配送」という文字のままexplodeしても、行は増えません。先にstr.splitで区切ってリストにします。str.splitは、指定した区切りの文字で文字を分ける機能です。
空のリストは、その行が空の値になります。
手順: 分類を1件ずつの行にして数える
次のコードは、架空の問い合わせの表 inquiries.xlsx の「分類」を1件ずつの行に分け、分類ごとの件数を表示して、inquiries_rows.xlsx という別の名前で保存します。読み込んだ元の表には書き込まないので、分ける前の形も手元に残せます。
import pandas as pd
# 問い合わせの表を読む(分けた表は別の名前で保存する)
table = pd.read_excel("inquiries.xlsx")
# 「請求,配送」を区切って、1つの値ごとに1行にする
table["分類"] = table["分類"].str.split(",")
rows = table.explode("分類", ignore_index=True)
rows["分類"] = rows["分類"].str.strip() # 区切りの後の空白を取る
print(rows)
print(rows["分類"].value_counts())
print("分類が空の行:", rows["分類"].isna().sum())
rows.to_excel("inquiries_rows.xlsx", index=False)
ignore_index=Trueは、分けた後の行の番号を0から振り直すための指定です。区切りの文字は、自分の表に合わせて書き換えます。
試した結果
問い合わせが5件だけの作り物の表で動かしました。分類は「請求,配送」「配送」「返品, 請求」(カンマの後に空白あり)、空欄、「請求,配送,返品」です。
- 5行の表が9行になり、受付番号1は2行、受付番号5は3行に分かれました
- 分類ごとの件数は、請求が3件、配送が3件、返品が2件でした
- 空欄だった受付番号4は空の1行のまま残り、「分類が空の行: 1」と表示されました
- 実行の前後で inquiries.xlsx のハッシュ値は変わりませんでした
動かしたのはMacの作業PCで、ライブラリはpandas 3.1.0とopenpyxl 3.1.5、Pythonは3.12.15です。Excelのアプリで開いた見た目は確かめていません。
自分で直すか、相談するかの判断
目安は、「1つのセルの区切りの文字が、表の中で1種類にそろっているか」です。カンマだけで区切られているなら、上のコードの区切りの文字を合わせるだけで使えます。
カンマと読点が混ざっている、「ほか」のような言葉が入っている、といった表は、先に表記をそろえる作業が要ります。次に入力する人に区切り方を決めてもらうか、入力の欄を分けるかは、表を使う人と相談して決めます。
つまずきやすいところ
- 区切りの後の空白を取らない: 試したときも、str.stripを外すと「 請求」(先頭に空白)が別の分類として数えられ、請求は2件と1件に分かれました。空白や全角・半角のそろえ方は、PythonでExcelの表の文字の前後の空白と全角・半角をそろえる手順で紹介しています
- str.splitをせずにexplodeする: 文字のままだと行は増えません。試したときも、表は5行のままでした
- 行の番号が重なったまま使う: ignore_indexを付けないと、同じ番号の行が並びます。試したときも、9行のうち番号の重なる行がありました。番号で行を探す処理の前に振り直します
- 値の数が決まっているなら列に分ける: 姓と名のように必ず2つに分かれるなら、PythonでExcelの1つの列を区切り文字で2つの列に分ける手順のほうが向いています
- 分類ごとに金額も集計したい: 分けた表を分類ごとにまとめる方法は、PythonでExcelのピボットテーブルのように集計する手順にまとめています
まとめ
- str.splitで区切ってリストにし、explodeで1つずつの行に広げます
- 区切りの後の空白は、str.stripで取り除いてから数えます
- 空欄の行は空の1行のまま残るので、件数を数えて確かめます
- 行の番号を振り直すときは、ignore_index=Trueを付けます
よくある質問
列に分けるのと、行に分けるのは、どう使い分けますか?
値の数が決まっているなら列、決まっていないなら行が向いています。姓と名のように必ず2つに分かれるならstr.splitのexpand=Trueで列に、分類のように1つから3つまで変わるならexplodeで行にすると、数えやすくなります。
2つの列を同時に行に分けられますか?
できます。explodeに列の名前のリストを渡します。公式の資料では、同じ行の中で、指定した列の値の数がそろっている必要があるとしています。試したときも、数がそろっていない行があるとValueErrorで止まりました。
分けた後に、元の1行の形に戻せますか?
受付番号でgroupbyして、分類をカンマでつなぎ直せば戻せます。試した表でも、groupbyのあとのaggに",".joinを渡すと、元と同じ並びの値に戻りました(カンマの後の空白は取れた形になります)。
区切りが「、」や「/」のときは?
str.splitに渡す区切りの文字を変えます。区切りが混ざっているなら、先に1種類にそろえてから分けます。
行の番号が同じものが並ぶのはなぜですか?
explodeは、元の行の番号を分けた行にそのまま写すためです。0から振り直したいときは、ignore_index=Trueを付けます。