PythonでExcelの文字列から番号やコードを抽出する手順|pandasのstr.extractで取り出す
Pythonのpandasで、Excelの備考の列の「注文番号A-1234(至急)」のような文字から、番号やコードの部分だけを正規表現で取り出す手順を解説します。全角の数字や小文字で取り出せない例も、架空のデータで試した結果とともに紹介します。
目次
この記事でわかること
- 備考の列のような文字から、決まった形の部分だけを取り出す方法(str.extract)
- 取り出した部分に名前を付けて、新しい列にする書き方
- 取り出せない行の数え方と、全角の数字・小文字・1行に2つのときのつまずき
- 自分の表で使う前に確かめること
「注文番号A-1234(至急)」のように、番号のまわりに別の言葉が付いた文字から、番号だけを毎回手で消していませんか。この記事では、pandasのstr.extractと正規表現で、決まった形の部分だけを取り出して新しい列にする手順を紹介します。
参考にしたのは、pandas 3.1.0の公式の資料(Series.str.extractのAPIリファレンスと、文字のデータの扱い方を説明したユーザーガイド)です。2026年10月30日に原文で読みました。例の注文の表は、この記事のために作った架空のものです。
先に結論: 形を正規表現で書き、名前の付いたグループで取り出す
取り出したい部分の形を正規表現で書き、括弧のグループに名前を付けて、str.extractに渡します。 グループごとに1つの列ができ、見つからない行は空になります。
| 書くもの | 例 |
|---|---|
| 英字1文字 | [A-Z] |
| 半角の数字4けた | [0-9]{4} |
| 名前付きのグループ | (?P<番号>…) |
| 大文字小文字を区別しない | flags=re.IGNORECASE |
str.extractのしくみ
str.extractは、正規表現の中の括弧(グループ)に当たった部分を、DataFrameの列として取り出します。資料によると、それぞれの文字について、正規表現に最初に一致したところからグループを取り出します。
結果は、元の行ごとに1行、グループごとに1列の表になります。グループに名前を付けていればその名前が、付けていなければ0・1のような番号が列の名前になります。一致しない行は空(NaN)です。
すべての一致を取り出したいときは、extractallを使います。資料では、最初の一致だけでなく、すべての一致を返すとしています。
手順: 備考の列から区分と番号を取り出す
次のコードは、架空の注文の表 orders.xlsx の「備考」の列から、「英字1文字-半角の数字4けた」の部分を取り出し、「区分」と「番号」の2つの列にして orders_extracted.xlsx に書き出します。orders.xlsx は書き換えません。
import pandas as pd
# 注文の表を読む(元のファイルは上書きしない)
orders = pd.read_excel("orders.xlsx")
# 「英字1文字-半角の数字4けた」を取り出し、区分と番号の列にする
found = orders["備考"].str.extract(r"(?P<区分>[A-Z])-(?P<番号>[0-9]{4})")
orders = orders.join(found)
print("取り出せなかった行:", orders["番号"].isna().sum())
orders.to_excel("orders_extracted.xlsx", index=False)
pandasと、xlsxを読み書きするopenpyxlは、先に入れておきます。番号の形が違うときは、[0-9]{4}の部分を自分の表の番号に合わせて書き換えます。
試した結果
作り物の注文の表(6行)の備考の列で動かしました。備考は「注文番号A-1234(至急)」「B-5678 再送」「a-9012 小文字」「番号なし」「C-1111とC-2222の2件」「D-1234(全角)」です。
- 区分と番号が取り出せたのは3行で、A・1234、B・5678、C・1111でした
- 「取り出せなかった行: 3」と表示されました。小文字の「a-9012」、「番号なし」、全角の数字の「D-1234」の行です
- 「C-1111とC-2222の2件」の行は、最初のC・1111だけが取り出されました
- 元のorders.xlsxは、実行の後も中身が1バイトも変わっていませんでした
Macの作業PCで、openpyxl 3.1.5とpandas 3.1.0をPython 3.12.15の上で使いました。Excelのアプリでの表示は見ていません。
自分で直すか、相談するかの判断
目安は、「取り出したい部分の形が、1つの決まりで書けるか」です。番号のけた数や区切りの記号が決まっていれば、この記事の書き方で取り出せます。
部署によって番号の形が違う、手入力で表記がばらばら、といった場合は、形を1つずつ洗い出して決まりを作るところから始まります。どの形を正しいとするかは、その番号を使う人と決めてから、取り出せなかった行を一覧にして確かめます。
つまずきやすいところ
- \dで全角の数字まで拾う: 数字を\dで書くと、全角の「1234」にも当たり、全角のまま取り出されました。試したときも、取り出した「1234」は半角の「1234」と一致しませんでした。半角だけを取り出すなら[0-9]と書き、全角が混ざる表は先にそろえます。そろえ方は、PythonでExcelの表の文字の前後の空白と全角・半角をそろえる手順で紹介しています
- 小文字が取り出せない: [A-Z]は大文字だけに当たります。flagsにre.IGNORECASEを渡すと、試したときも「a-9012」が取り出せました
- 1行に2つある番号の後ろを見落とす: str.extractは最初の1つだけです。すべてが要るならextractallを使います
- 区切りの記号で分けられる列: 「山田 太郎」のように決まった記号で分けられるなら、PythonでExcelの1つの列を区切り文字で2つの列に分ける手順の方法のほうが簡単です
- 取り出した番号で行を絞りたい: 取り出した列を条件にして行を取り出す方法は、PythonでExcelの表から条件に合う行を抽出する手順にまとめています
まとめ
- 取り出したい部分の形を正規表現で書き、str.extractに渡します
- グループに(?P<名前>…)で名前を付けると、その名前の列ができます
- 一致しない行は空になるので、取り出せなかった行の数を数えます
- \dは全角の数字にも当たるので、半角だけなら[0-9]と書きます
よくある質問
1つのセルに番号が2つあるときは、どうなりますか?
str.extractは、最初に見つかった1つだけを取り出します。資料でも、それぞれの文字の最初の一致からグループを取り出すとしています。全部を取り出したいときは、すべての一致を返すextractallを使います。
取り出せなかった行は、どうなりますか?
空(NaN)になります。資料の例でも、一致しないものはNaNになるとしています。取り出した後に、空の行の数を数えて確かめます。
取り出した列の名前は、どうやって付けますか?
正規表現のグループに名前を付けます。(?P<番号>…)のように書くと、その名前が列の名前になります。資料では、グループに名前があればそれが列の名前に使われ、なければ番号が使われるとしています。
大文字と小文字を区別せずに取り出せますか?
flagsにre.IGNORECASEを渡します。資料では、flagsにreの印を渡して、大文字と小文字などの一致のしかたを変えられるとしています。架空の表でも、小文字の「a-9012」が取り出せるようになりました。
正規表現を使わずに取り出す方法はありますか?
決まった区切り文字で分けられるなら、str.splitで列を分ける方法があります。区切りがなく、形だけが決まっている部分を取り出すときは、str.extractのほうが向いています。