PythonでExcelの表の上や下に余計な行があるシートを読み込む手順|表の部分だけを取り出す
表の上にタイトル、下に合計の行があるExcelのシートを、pandasのread_excelで表の部分だけ読み込む手順を解説します。skiprows・usecols・nrowsの決め方と、合計の行が混ざって数字が倍になるつまずきを、架空の表で試しました。
目次
この記事でわかること
- 表の上にタイトルや作成日の行があるシートを、見出しの行から読み込む方法
- 表の下の合計や注記の行を読み込まない方法
- 左の空いた列や右のメモの列を除いて、表の列だけを読み込む方法
- 読み込めたかを、行数・列名・合計で確かめる方法
社内で配られる報告のExcelには、表の上にタイトルや作成日が、下に合計や注記が書かれていることがよくあります。そのままpandasで読み込むと、列の名前がおかしくなったり、合計の行が明細に混ざったりします。この記事では、read_excelの引数で表の部分だけを読み込み、正しく読めたかを確かめるまでの流れをまとめます。
参考にしたのは、pandas 3.1.0の公式の資料にあるpandas.read_excelのページで、2026年11月2日に原文を読みました。例に出てくる店舗・数量・売上は、試すために作った架空の表です。
先に結論: 上はskiprows、列はusecols、下はnrowsかskipfooterで決める
表の上の行の数をskiprowsに、表のある列をusecolsに、明細の行の数をnrowsに渡すと、表の部分だけを読み込めます。 明細の行の数が変わるときは、nrowsの代わりにskipfooterで下の行の数を渡します。引数の役割は、次のとおりです。
| 引数 | 決めること | 試した表で渡した値 |
|---|---|---|
| skiprows | 表の上で飛ばす行の数 | 3(タイトル・作成日・空の行) |
| usecols | 読み込む列の範囲 | "B:E"(日付から売上まで) |
| nrows | 見出しの下で読み込む行の数 | 6 |
| skipfooter | 表の下で除く行の数(nrowsの代わり) | 3(空の行・合計・注記) |
read_excelの引数のしくみ
pandasの資料では、skiprowsはファイルの初めから飛ばす行の数で、行の番号のリストも渡せるとしています。飛ばした後の最初の行が、列の名前になります。headerは列の名前に使う行の位置(0から数える)で、skiprowsの代わりに使うこともできます。
usecolsには、"A:E"のようなExcelの列の文字と範囲を渡せます。範囲は両端の列を含みます。nrowsは読み込む行の数で、見出しの行は数に入りません。skipfooterは、最後から除く行の数です。
手順: 報告のシートから明細の表だけを読み込む
次のコードは、架空の報告のファイル report.xlsx の「売上」のシートから、B列からE列の明細の表だけを読み込み、行数・列名・売上の合計を表示してから sales_clean.xlsx に保存します。report.xlsx には何も書き込みません。
import pandas as pd
table = pd.read_excel(
"report.xlsx",
sheet_name="売上",
skiprows=3, # 上の3行(タイトル・作成日・空の行)を飛ばす
usecols="B:E", # 表のあるB列からE列だけ
nrows=6, # 見出しの下の明細6行だけ
)
print(len(table), list(table.columns)) # 行数と列名を確かめる
print(table["売上"].sum()) # シートの合計の行と見比べる
table.to_excel("sales_clean.xlsx", index=False)
xlsxのファイルを扱うために、pandasと一緒にopenpyxlも入れておきます。読み込んだ後の合計を、シートに書かれた合計の行と見比べると、行の取りこぼしや合計の行の混ざりに気づけます。
試した結果
架空の報告のシートで動かしました。1行目にタイトル、2行目に作成日、3行目は空で、4行目のB列からE列に見出し、その下に明細が6行あります。明細の下に空の行・合計の行・注記の行があり、A列は空いていて、G列には「要確認」というメモが1つあります。
- 読み込んだ行数は6、列名は日付・店舗・数量・売上の4つでした
- 売上の合計は84,000で、シートの合計の行に書いた値と同じでした
- 数量と売上は整数の列、日付は日付の列として読み込まれました
- nrows=6の代わりにskipfooter=3を渡しても、同じ6行が読み込めました
- sales_clean.xlsx には4列・6行の表が入りました。元の report.xlsx は、実行の前後でハッシュ値が変わりませんでした
動かしたのはMac の作業PCで、入っていた版は、openpyxlが3.1.5、pandasが3.1.0、Python本体が3.12.15です。保存した表はopenpyxlで読み込み直して確かめただけで、Excelのアプリで開いたときの見え方は確かめていません。
自分で決めるか、相談するかの判断
目安は、「毎月のシートで、表の上と下の行の数と、表のある列が同じか」です。同じなら、skiprows・usecols・nrows(またはskipfooter)の値を決めておけば、毎月そのまま使えます。
月によって表の位置が動いたり、合計の行が途中に入ったりするシートは、値を決めておくことができません。シートを作っている人に、表の置き方をそろえられないか、明細だけのシートを別に出せないかを相談します。
つまずきやすいところ
- 列の名前がすべて「Unnamed」になる: 飛ばす行を1つ少なく数え、skiprows=2にすると、見出しの代わりに空の行が列の名前になりました。列名がUnnamed: 0のように並んだら、飛ばす行の数を数え直します
- 知らない列が増えている: usecolsを付けずに読み込むと、空いたA列とメモのあるG列のあたりが、Unnamed: 0・Unnamed: 5・Unnamed: 6という列として入りました。表のある列の範囲をusecolsで渡します
- 合計の行まで明細に入り、合計が倍になる: nrowsもskipfooterも付けずに読み込むと、空の行・合計の行・注記の行まで入り、9行になりました。売上の合計は168,000で、本当の合計の倍でした。数量の列も、空の行に合わせて小数の列になっていました
- skipfooterで空の行が残る: skipfooterは下から数える行の数で、空の行も1行に数えます。試したときも、合計と注記の2行だけのつもりでskipfooter=2にすると、空の行が1行残って7行になりました
- nrowsに見出しの行を入れて数える: pandasの資料では、nrowsは見出しの行を含まない数としています。明細が6行なら、nrowsは6です
- 複数のシートを続けて読みたい: シートの名前を変えながら同じ読み方をする方法は、PythonでExcelの複数シートを読み込んでまとめる手順で紹介しています
- 番号の先頭の0が消える: 社員番号や商品コードの0を残したまま読み込む方法は、PythonでExcelのコード番号の先頭の0を消さずに読み込む手順にまとめています
- 見出しの名前がそろっていない: 読み込んだ後に列の名前を決まった名前に直す方法は、PythonでExcelの表の列名をそろえて変更する手順が参考になります
まとめ
- 表の上の行はskiprows、表のある列はusecolsで決めます
- 表の下の行は、明細の行の数が決まっていればnrows、下の行の数が決まっていればskipfooterで除きます
- 読み込んだ後に、行数・列名・合計を、シートの合計の行と見比べます
- 表の位置が毎回変わるシートは、置き方をそろえられないかを作る人と相談します
よくある質問
読み込んだ表は、元のExcelのファイルに書き込まれますか?
書き込まれません。記事のコードは元の報告のファイルを開くだけで、表の部分は別のファイルの sales_clean.xlsx に保存します。試したときも、元の report.xlsx のハッシュ値は実行の前後で変わりませんでした。
skiprowsとheaderは、どちらを使えばよいですか?
見出しの行の位置を決めるという意味では、どちらでも同じ結果にできます。試した表でも、skiprows=3とheader=3のどちらでも、列名は日付・店舗・数量・売上の4つになりました。記事では、飛ばす行の数が目で数えやすいskiprowsを使っています。
表の行の数が月によって変わるときは、どうしますか?
下に付く行の数が毎回同じなら、nrowsの代わりにskipfooterで下の行を除きます。試した表では、下の空の行・合計・注記の3行をskipfooter=3で除くと、nrows=6と同じ6行が読み込めました。
表の上の行の数も月によって変わるときは、どうしますか?
上の行の数が決まっていないシートでは、skiprowsの数を固定できません。見出しの行に必ずある言葉(たとえば「日付」)を探して、その行の位置を先に調べてから読み込む方法を考えます。毎回の形がそろわない場合は、シートを作る人と、表の置き方をそろえられないかを相談します。
列の順番を、読み込んだあとに入れ替えられますか?
入れ替えられます。pandasの資料では、usecolsで選んだ列の順番は使われないとしています。並べたい順番があるときは、読み込んだ後に列の名前のリストで並べ直します。