PythonでExcelの1つの列を区切り文字で2つの列に分ける手順|pandasのstr.splitで姓と名を分ける
Excelの表で氏名のように1つの列に入った文字を、Pythonのpandasのstr.splitで空白の前後の2つの列に分ける手順を、公式の資料をもとに解説します。区切りが無い行、空白が2つ以上ある行、全角の空白などのつまずきも紹介します。
本記事はプロモーションを含みます。紹介する情報は、実際の成果や効果を保証するものではありません。
目次
この記事でわかること
- Excelの1つの列に入った文字を、pandasのstr.splitで2つの列に分ける方法
- 分ける回数(n)と、できる列の数の関係
- 区切りが無い行や、空白が2つ以上ある行の扱い
- 分けた列を足して、別のExcelのファイルに保存する手順
名簿の「氏名」の列に「山田 太郎」のように姓と名が続けて入っていると、姓だけで並べ替えたり、ほかの表の姓の列とつなげたりするときに困ります。1件ずつ手で切り分けるのは時間がかかり、写しまちがいも起きます。ここでは、Pythonのpandasを使って、空白を区切りにして1つの列を姓と名の2つの列に分け、新しいファイルに残すところまでを、順を追って見ていきます。記事用に用意した架空の名簿でコードを動かし、出てきた結果もあわせて紹介します。
str.splitの指定の意味は、pandasの公式の資料にあたって確認しました(APIリファレンスとユーザーガイド、確認日は2026年10月25日)。名簿は架空のもので、実在の人の名簿は使っていません。
先に結論: str.splitにexpand=Trueとn=1を付けて2つの列にする
先に結論を書くと、1つの列を2つに分けるときは、str.splitに区切りの文字を渡し、expand=Trueで列に分け、n=1で最初の区切りだけで分けます。 よく使う指定は、次の4つです。
| 指定 | 役割 |
|---|---|
| pat | 区切りの文字 |
| n | 分ける回数の上限 |
| expand | 列に分けるか |
| regex | 正規表現として扱うか |
str.splitで1つの列を区切りで分ける
pandasのstr.splitは、列の中のそれぞれの文字を、指定した区切りの文字で前から分ける働きをします。区切り(pat)を指定しないときは、空白で分けます。
初期の設定(expand=False)では、結果は1つの列のままで、セルごとに分けた文字のリストが入ります。expand=Trueを付けると、分けた文字が別々の列に入った表(DataFrame)になります。ユーザーガイドの例でも、空欄(NaN)のセルは、分けた後も空欄のままです。
区切りに1文字を渡すと、そのまま文字として扱われます。資料によると、regexを付けないときは、区切りが1文字なら文字として、2文字以上なら正規表現として扱うとしています。
分ける回数とできる列の数
nは、分ける回数の上限です。初期の設定では、区切りが見つかるたびにすべて分けます。n=1にすると最初の区切りだけで分け、残りは後ろの列にまとめて入ります。
expand=Trueのときにできる列の数は、すべての行のうち最も多く分けられた回数に1を足した数です。分けられた回数がほかの行より少ない行は、足りない列が空になります。資料には、nは上限であって列の数を決めるものではないため、列の数をそろえたいときは結果をreindexするとよい、とも書かれています。
手順: 氏名の列を姓と名に分けて別のファイルに保存する
次のコードは、架空の名簿 members.xlsx(社員番号と氏名の2列)を読み込み、氏名の列を最初の空白で分けて、姓と名の2つの列を表の右に足します。結果は新しいファイル(members_split.xlsx)として保存し、元のmembers.xlsxは書き換えません。自分の名簿で試すときは、列名とファイル名をその表に合わせ、作業の前に元のファイルの控えを取っておきます。
import pandas as pd
# 元の名簿を読み込む(このファイルは書き換えない)
src_file = "members.xlsx"
df = pd.read_excel(src_file)
# 全角の空白を半角にそろえ、最初の空白だけで2つの列に分ける
names = df["氏名"].str.replace(" ", " ").str.split(" ", n=1, expand=True)
# 空白が無い行しか無くても2列になるように、列を0と1にそろえる
names = names.reindex(columns=[0, 1])
df["姓"] = names[0]
df["名"] = names[1]
print(df)
# 姓と名の列を足した表を、別の名前で保存する
out_file = "members_split.xlsx"
df.to_excel(out_file, index=False)
実行する前に、pandasと、新しい形式のExcelのファイル(xlsx)を扱うopenpyxlを入れておきます。氏名の列には全角の空白で区切った行が混ざることがあるため、分ける前にstr.replaceで半角の空白に置き換えています。reindexの行は、資料にある列の数のそろえ方に沿ったものです。元の氏名の列は残したまま、姓と名の列を足しています。
実行した結果
6人分の架空の名簿(半角の空白で区切った行、全角の空白で区切った行、空白の無い行、氏名が空欄の行、空白が2つある行を含む)で試したところ、次のようになりました。
- 社員番号・氏名・姓・名の4列、6行の表になりました
- 「山田 太郎」「鈴木 花子」は、姓と名にそのまま分かれました
- 全角の空白で区切った「田中 一郎」も、姓が田中、名が一郎に分かれました
- 空白の無い「佐藤」は姓が佐藤、名が空になり、氏名が空欄の行は姓も名も空になりました
- 空白が2つある「渡辺 マリア 恵」は、姓が渡辺、名が「マリア 恵」になりました
- 保存したmembers_split.xlsxを開くと、4列の見出しの下に6行が並んでいました。読み込んだ元のmembers.xlsxは、実行の前と同じままでした
動かしたのは Mac の作業PCで、Python 3.12.15、pandas 3.0.6、openpyxl 3.1.5 の組み合わせです。
自分で直すか、相談するかの判断
うまく分けられたかは、「名が空になった行」と「名の中に空白が残った行」を数えて見分けます。架空の名簿では、名が空の行が2行(空白の無い行と空欄の行)、名に空白が残った行が1行でした。これらの行は、元の氏名を見て、手で直すか、そのままにするかを決めます。氏名が空欄の行を先に洗い出したいときは、PythonでExcelの表の空欄を見つけて一覧にする手順のやり方が使えます。
どこまでが姓でどこからが名かは、文字だけでは決められないことがあります。名前の途中に空白がある人や、姓と名の順が逆に入っている行があるときは、プログラムで分けた結果を正しいと決めつけず、名簿を管理している人に確かめます。
つまずきやすいところ
- expand=Trueを付け忘れる: 1つの列のまま、セルにリストが入ります。架空の名簿では、そのまま書き出すと「['山田', '太郎']」のような文字列がセルに入りました
- nを付けずに分ける: 「渡辺 マリア 恵」の行が3つに分かれ、列が3つになりました。0と1の列だけを使うと、「恵」が抜け落ちます
- 全角の空白が混ざっている: 置き換えをしないで分けると、「田中 一郎」は分かれず、名が空になりました。空白や全角・半角をまとめてそろえる方法は、PythonでExcelの表の文字の前後の空白と全角・半角をそろえる手順が参考になります
- どの行にも区切りが無い: 架空の2人分の名簿(「佐藤」「高橋」)で試すと、列が1つしかできず、1の列を取り出そうとしたところでKeyErrorで止まりました。記事のコードのreindexの行は、これを防ぐためのものです
- 区切りに2文字以上を渡す: regexを付けないと正規表現として扱われます。架空の文字「A..B」を「..」で分けると、「..」が任意の2文字として扱われ、空の文字が3つ並んだだけになりました。regex=Falseを付けると、AとBに分かれました
- 分けた列でほかの表とつなぐとき: 姓などの列を使ってほかの表とつなげる手順は、PythonでExcelの2つの表を共通の列で結合する手順にあります。分けた後の文字の前後に空白が残っていないかを先に確かめます
まとめ
- 1つの列を2つに分けるときは、str.splitにexpand=Trueを付け、n=1で最初の区切りだけで分けます
- 全角の空白が混ざる列は、分ける前に半角にそろえます
- どの行にも区切りが無くても2列になるように、reindexで列をそろえます
- 名が空の行や、名に空白が残った行を数えて確かめ、結果は新しいファイルとして保存して元の表は残します
よくある質問
expand=Trueを付けないと、どうなりますか?
1つの列のまま、セルごとに分けた文字のリストが入ります。架空の名簿でも、リストのままExcelに書き出すと、「['山田', '太郎']」のような1つの文字列としてセルに入りました。2つの列にしたいときはexpand=Trueを付けます。
空白が無い行は、どう分けられますか?
区切りが見つからないので、前の列に元の文字がそのまま入り、後ろの列は空(NaN)になります。架空の名簿では、「佐藤」の行は姓が佐藤、名が空になりました。
空白が2つ以上ある行は、どう分けられますか?
n=1を付けると、最初の空白だけで分けて、残りは後ろの列にまとめて入ります。架空の名簿の「渡辺 マリア 恵」は、姓が渡辺、名が「マリア 恵」になりました。nを付けないと、列が3つにできます。
後ろから分けることはできますか?
rsplitを使うと、文字の終わりの側から分けられます。pandasの資料では、rsplitはsplitと逆の向き、つまり文字の終わりから始めに向かって分けるとしています。
分けると、元のExcelのファイルも変わりますか?
変わりません。記事のコードは元のファイルを読み込むだけで、姓と名の列を足した表は別の名前で保存します。架空の名簿で試したときも、元のmembers.xlsxの中身はそのままでした。