PythonでExcelの表の空欄を決めた値で埋める手順|pandasのfillnaで列ごとに埋め方を変える
Excelの表の空欄を、Pythonのpandasで列ごとに決めた値や上の行の値で埋める手順を、fillnaとffillの公式の資料をもとに解説します。埋めてはいけない列の考え方と、空欄に見えて埋まらないセルの見つけ方も紹介します。
本記事はプロモーションを含みます。紹介する情報は、実際の成果や効果を保証するものではありません。
目次
この記事でわかること
- Excelの表の空欄を、列ごとに決めた値で埋める方法(pandasのfillna)
- 上の行と同じ値が省略された空欄を、上の値で埋める方法(ffill)
- 埋めてよい列と、埋めずに残す列の分け方
- 埋めた後に空欄の数を数え直し、別のファイルに保存する手順
手で入力された表には、「件数が0の日は書いていない」「同じ店舗の2行目からは店舗名を省いている」といった空欄がよくあります。そのままPythonで集計すると、空欄の行が数に入らなかったり、店舗ごとにまとめられなかったりします。この記事では、空欄の意味を列ごとに決めて、pandasで埋める手順を、架空の作業記録の表で動かした結果とあわせて説明します。
fillnaとffillの働きは、pandasの公式の資料(3.1.0の版のAPIリファレンスと、欠損値を扱うユーザーガイド)で確かめています。原文を読んだのは2026年10月27日です。表の店舗名・担当者名・件数はすべて作ったもので、実際の記録ではありません。
先に結論: 空欄の意味を列ごとに決めてから埋める
先に結論を書くと、空欄の意味が「0件」「特になし」「上と同じ」のように決まっている列だけを埋め、意味の分からない列は埋めずに残します。 決まった値で埋める列はfillnaに辞書で渡し、上と同じ値の列はffillで埋めます。この記事の表では、次のように分けます。
| 列 | 空欄の扱い |
|---|---|
| 店舗 | 上の行の値で埋める |
| 担当 | 埋めずに残す |
| 件数 | 0で埋める |
| 備考 | 「なし」で埋める |
pandasで空欄はどう読まれるか
read_excelで読み込むと、何も入っていないセルは欠損値(NaN)になります。pandasの資料では、欠損値を見つけるにはisnaかnotnaを使うとしています。表全体にisnaを使い、sumで列ごとに数えると、どの列にいくつ空欄があるかが分かります。空欄を一覧にする方法は、PythonでExcelの表の空欄を見つけて一覧にする手順で詳しく紹介しています。
決めた値で埋める(fillna)
fillnaは、欠損値を指定した値に置き換える働きをします。値を1つだけ渡すと、表のすべての空欄がその値になります。
列ごとに違う値で埋めたいときは、「列名: 埋める値」の辞書を渡します。資料によると、辞書に含まれない列は埋められません。埋めたくない列は、辞書に書かなければそのまま残ります。
fillnaは、空欄を埋めた新しい表を返します。log = log.fillna(...)のように、結果を受け取り直して使います。
上の行の値で埋める(ffill)
ffillは、最後にあった値を、次の値が出てくるまで下へ広げて空欄を埋める働きをします。セルの結合を解除した表のように、同じ店舗の2行目以降が空欄になっている列に向いています。
資料によると、limitを付けると、続けて埋める空欄の数に上限を付けられます。前の値が無い先頭の空欄は、ffillでは埋まりません。
手順: 作業記録の表の空欄を埋めて別のファイルに保存する
次のコードは、架空の作業記録 work_log.xlsx(店舗・担当・件数・備考の4列)を読み込み、店舗は上の行の値で、件数は0で、備考は「なし」で埋めます。担当は誰だったかを推測できないので、埋めずに残します。埋めた表はwork_log_filled.xlsxとして書き出し、work_log.xlsxは書き換えません。ご自分の表に当てはめるときは、列名と埋める値を表に合わせてください。
import pandas as pd
# 作業記録を読み込む(work_log.xlsx そのものは変えない)
log = pd.read_excel("work_log.xlsx")
print("埋める前:", log.isna().sum().to_dict())
# 店舗は、同じ店舗の2行目から省かれているので、上の行の値で埋める
log["店舗"] = log["店舗"].ffill()
# 件数と備考は決めた値で埋める(担当は推測しないので辞書に入れない)
log = log.fillna({"件数": 0, "備考": "なし"})
log["件数"] = log["件数"].astype(int)
print("埋めた後:", log.isna().sum().to_dict())
# 埋めた表を、別の名前で書き出す
log.to_excel("work_log_filled.xlsx", index=False)
実行には、pandasとあわせて、xlsxを読み書きするためのopenpyxlを入れておきます。件数の列は、空欄があると小数の形で読み込まれるため、埋めた後にastype(int)で整数に戻しています。
実行した結果
架空の作業記録(5行。店舗は2つ目以降の行が空欄、担当に空欄1つ、件数に空欄1つ、備考に空欄3つと、空白の文字だけのセル1つ)で動かしました。
- 埋める前は、店舗3・担当1・件数1・備考3の空欄が数えられました
- 埋めた後は、店舗・件数・備考の空欄が0になり、担当の空欄1つだけが残りました
- 店舗の列は、空欄の行が直前の店舗名で埋まり、件数の空欄は0、備考の空欄は「なし」になりました
- 備考の、空白の文字だけが入ったセルは空欄として数えられず、埋まらずにそのまま残りました
- 書き出したwork_log_filled.xlsxを読み直すと件数は整数で、読み込んだwork_log.xlsxのほうは実行の前後でバイト単位で同じでした
実行環境はMacの作業PCで、Python 3.12.15 に pandas 3.1.0 と openpyxl 3.1.5 を入れて動かしました。
自分で直すか、相談するかの判断
判断の目安は、「空欄の意味を、表を作った人の決まりとして説明できるか」です。「件数が0の日は書かない」「同じ店舗の行は店舗名を省く」のように、入力のしかたが決まっている列は、自分で埋めて進められます。
担当者や金額のように、空欄が「書き忘れ」か「該当なし」か分からない列は、埋めると事実と違う表になるおそれがあります。埋めずに残した行を一覧にして、表を作った人に確かめてから扱いを決めます。
つまずきやすいところ
- 表全体を1つの値で埋める: 架空の表でfillna(0)としたところ、担当の空欄まで0になりました。pandas 3.1.0では、文字の列を数値で埋めると、将来の版ではエラーになるという警告(Pandas4Warning)も出ました。列ごとに辞書で値を決めます
- 辞書の列名をまちがえる: 「件数」を「件 数」と書くと、エラーにならないまま件数の空欄が残りました。埋めた後に空欄の数を数え直します
- 結果を受け取らない: log.fillna(...)だけを書いて受け取り直さないと、logの空欄はそのままでした
- 先頭の行が空欄: 先頭が空欄の列は、ffillの後も先頭だけ空欄のままでした
- 空欄を残したまま整数にする: 件数の空欄を埋める前にastype(int)を使うと、エラーで止まりました。埋めてから整数に戻します
- 空白の文字だけのセル: 見た目は空でも空白が入ったセルは、欠損値として扱われず、fillnaでは埋まりません。前後の空白の消し方は、PythonでExcelの表の文字の前後の空白と全角・半角をそろえる手順で紹介しています
- 埋めた後に範囲で数えたいとき: 件数や金額を範囲に区切って数える方法は、PythonでExcelの数値を区切って範囲ごとの件数を数える手順にまとめています
まとめ
- 空欄は、意味が決まっている列だけを埋め、意味の分からない列は埋めずに残します
- 決まった値で埋める列は、fillnaに「列名: 値」の辞書で渡します
- 同じ値が省略された列は、ffillで上の行の値を下へ広げて埋めます
- 埋めた後はisnaで空欄の数を数え直し、結果は別のファイルに書き出して元の表を残します
よくある質問
表の空欄を全部まとめて0にしてもよいですか?
おすすめしません。fillnaに値を1つだけ渡すと、すべての列の空欄がその値になります。架空の表で試すと、担当者の名前の列の空欄まで0になりました。列ごとに値を決め、辞書で渡す方が安全です。
辞書に書いた列名がまちがっていると、どうなりますか?
エラーにならず、その列は埋まりません。pandasの資料では、辞書に含まれない列は埋めないとしています。架空の表で列名を1文字まちがえたときも、何も言われずに空欄が残りました。埋めた後に、isnaで空欄の数を数え直して確かめます。
上の行の値で埋めるffillで、いちばん上の行の空欄はどうなりますか?
空欄のまま残ります。ffillは、それより前にある値を下へ広げる働きなので、前に値が無い先頭の空欄は埋まりません。架空のデータでも、先頭が空欄の列は、ffillの後も先頭だけ空欄でした。
件数の列が、3.0のように小数で表示されるのはなぜですか?
空欄のある数値の列は、読み込んだ時点で小数の形になるためです。架空の表でも、件数の列は小数の形で読み込まれました。空欄を埋めた後にastype(int)で整数に戻せます。空欄が残ったまま整数にしようとすると、エラーで止まりました。
空欄を埋めると、元のExcelのファイルも変わりますか?
変わりません。記事のコードは元のファイルを読むだけで、埋めた表は別の名前のファイルに書き出します。試したときも、読み込んだwork_log.xlsxは実行の前後で同じでした。