この記事でわかること

  • 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で空欄の数を数え直し、結果は別のファイルに書き出して元の表を残します