Excelの複数シートをpandasで一つの一覧にするなら、対象のシートを決め、見出しと列名をそろえてから concat で縦に連結します。全シートを無条件に混ぜると、集計表まで取り込んだり、同じ意味の列が別々になったりします。元シート名を残し、取り込み前後の行数と合計を照合しましょう。

対象は、Pythonで一枚の表を読めるようになり、支店別・月別のExcel一覧をまとめたい社会人です。本稿は同じ種類の明細を下へ積む「縦の連結」を扱います。注文と顧客台帳をキーで横につなぐ処理は、pandasのmergeで行数を確認する手順へ進んでください。

仕様と講座情報の確認日:2026年10月9日。pandas公式のread_excel、concat、シート名一覧のAPIを参照しました。公式文書は3.0.6表示、本稿の自作教材はPython 3.12.14・pandas 2.2.3・openpyxl 3.1.5で実行しました。実在の業務帳票の検証結果ではありません。

複数シートを混ぜる前に、対象と列の意味をそろえる

sheet_nameの戻り値と、concatの役割を分ける

read_excel はExcelを読み取る入口です。一つのシート名を指定すると、その表をDataFrameとして受け取れます。シート名のリストを指定した場合や sheet_name=None の場合は、複数のDataFrameが入った辞書を受け取ります。読み込めたことと、それらが一つの一覧になったことは別です。

辞書には「東」の表、「西」の表という対応が残っています。この対応を理解せずに値だけ取り出して連結すると、後で間違いを見つけたとき、どのシートの行だったのか分かりにくくなります。まずはシート名と表の行数を並べて眺め、取り込む単位を確認するところから始めます。

concat は複数の表を指定した方向へ連結します。同じ明細を縦に積む教材では axis=0 の方向を使います。ignore_index=True は連結後の行番号を振り直す指定です。注文IDの重複を取り除く設定ではありません。行番号がきれいになったので重複も消えた、と解釈しないでください。

一方、各シートの二行目を同じ顧客だと仮定して横に並べる処理は、この教材の目的に合いません。支店ごとの行順が変わるだけで対応が崩れます。同じ種類の行を増やしたいのか、別の表から項目を付け足したいのかを、コードを書く前に文章で説明できるようにしましょう。

例えば「東支店二件と西支店二件を合わせて四件にする」は縦連結です。「四件の注文へ顧客名を付ける」はキーで照合する結合です。似た日本語でも、必要な確認が違います。この区別を最初に置くと、検索で見つけた短いコードを別の目的へ流用する失敗を減らせます。

読み込み方を決めるための比較
指定・処理受け取るもの向いている場面先に確認すること
sheet_name='東'一つのDataFrame一枚だけ調べる対象名が正しいか
sheet_name=['東','西']表を収めた辞書解析条件が同じ複数表見出し行が同じか
sheet_name=None全シートの表を収めた辞書全体の調査集計・説明表が混ざらないか
ExcelFileで個別に読む指定ごとのDataFrame見出し行が異なる表シートごとの設定
concatで縦に連結連結した表同じ明細を積む列の意味と採用行数

明細シートを選び、集計シートを除外する理由を残す

一つのブックには、明細、合計、入力手順、前年の控えが入っていることがあります。どれもExcelのシートですが、同じ粒度のデータではありません。明細四件の金額に「合計400」という一行を加えると、集計値を再度足すことになります。コードが正常終了しても、一覧の意味は変わってしまいます。

そこで、今回取り込むシートを名前で指定します。「東」「西」を採用し、「集計」は確認用として除外する、と決めます。名前に「集計」という文字があるから自動で除く方式より、対象を明示する方式が初学者には追いやすくなります。名称から推測するルールは、命名規則が決まってから検討します。

採用リストに書いたシートが存在しない場合は、勝手に残りだけ処理しません。西支店の提出がなくても東支店だけで結果が出る仕組みでは、欠落が見えにくいからです。「対象シート不足」として止め、提出漏れか名前の変更かを確かめます。除外と欠落は、違う状態として記録してください。

月別の表なら、対象期間にも同じ注意が必要です。四月から六月をまとめたいのに、五月だけ名前が変わって読めなかった場合、一見きれいな二か月分の表が完成します。予定していたシートの集合と、実際に存在する集合を比較してから取り込みます。行数だけでは、期間の欠落まで見つけられません。

除外の理由は短いメモで十分です。「集計:明細の再集計であり取り込まない」「説明:操作手順でありデータではない」と書きます。後で担当者が変わったときに、特定のシートを読まないことが意図的な判断だったと分かります。判断の根拠がない除外は、単に問題の行を隠しただけかもしれません。

今回は対象を固定した小さな教材です。実務で毎月新しいシートが増えるなら、対象期間の一覧と照合する工程を追加します。「全シート取得なら将来の追加にも対応できる」と決めつけず、追加された表が明細と同じ構造か確認してください。便利さと取り込み範囲は別々に考えます。

見出し行の位置と、列名の表記揺れを別々に調べる

東のシートは一行目から「注文ID」「金額」と始まり、西は一行目に「西支店の一覧」というタイトル、二行目に「受注番号」「金額(円)」があります。この二枚を同じ header=0 で読むと、西のタイトルが列名として扱われます。列名を変更する前に、どの行が本当の見出しかを見てください。

header の行番号はゼロから数えます。一行目が見出しなら0、二行目なら1です。Excel画面の行番号と一つずれる点をメモしておくと、設定を見直しやすくなります。読み込み後の列名と最初の数行を確認し、見出しがデータ行として残っていないか、逆に明細一行目を見出しにしていないかを見ます。

次に、意味が同じ列へ共通名を付けます。教材では「注文ID」と「受注番号」を order_id、「金額」と「金額(円)」を amount に対応させます。この対応は編集部の架空帳票について決めたものです。実務で注文と受注の番号体系が同じとは限らないため、語が似ているだけで同じ列へまとめないでください。

金額の単位も名前だけでは分かりません。「金額」が税込で「金額(円)」が税抜なら、表記をそろえても値の意味は一致しません。列名対応表の横へ、単位、税込・税抜、対象期間などを記録します。この教材ではどちらも同じ定義の円額という前提を置き、通貨換算や税の再計算は行いません。

前後の空白を取り除く程度の処理でも、変換後の列名を確認します。「金額」と「金額 」が別々に存在した場合、空白を除くと同名になります。片方が備考用だった可能性もあります。列名を整えることを、不要な列を自動で消すことと混同しないようにしましょう。

基本の読み込みや保存をまだ説明しにくい場合は、PythonによるExcel自動化の学習順で一枚の表から練習できます。複数シートへの拡張は、その一枚の読み取りで何を確認していたかを言葉にできてから進めると、設定の違いを見つけやすくなります。

列が増えたとき、outerとinnerだけで片付けない

列名が一致しない表をそのまま縦に連結すると、通常は両方の列が残り、値がない側へ欠損が入ります。「金額」と「金額(円)」が別の列になれば、東の行には前者、西の行には後者の値が入ります。一つの金額列だと思って集計すると、片方の支店だけを集計する結果になりかねません。

そこで join='inner' に変更して共通列だけを残せばよい、という考えにも注意が必要です。共通でない列が不要と決まっていれば使えますが、重要な金額列を落としてしまう可能性があります。表が細くなりエラーが消えたことは、必要な情報が残ったことを示しません。

教材では期待する列を order_id と amount の二つへ限定し、不足や追加があれば止めます。追加列が悪いという意味ではありません。新たに税区分や取消区分が届いたなら、それを無視してよいか確認する必要があります。いったん止めることで、帳票の仕様変更を人が判断できるようにします。

列の並び順だけが違う場合は、期待する順番へ並べ直せます。集合として同じ列がそろっていることを確かめた後、必要な順へ選び直す順序が大切です。先に二列だけ選ぶと、追加された重要な列に気付かず、いつもの二列だけで処理が進みます。

列名の重複も別に確認します。二つの元列を同じ amount へ変換したとき、列の集合だけを比べる検査では不十分です。重複した列名を先に検出することで、表の形が曖昧な状態を受け入れずに済みます。明細のID重複とは違う、表の見出しの重複を扱う確認です。

列が違う場合に選ぶ対応
状態対応の例その前の確認
意味が同じで表記だけ違う対応表でrename単位・定義も同じか
見出し行がずれているシートごとにheaderを指定先頭の明細が残るか
必要な列がない取り込みを保留提出漏れか帳票変更か
新しい列が増えた追加理由を確認取消などの重要情報でないか
変換後に列名が重複対応表を修正するまで停止元列の意味を混ぜていないか

元シート名を残し、連結後も行の出所をたどる

結果へ source_sheet という列を付けて、東または西を記録します。この列は見た目を整えるためではありません。金額が違う、注文IDが空欄だった、という行を元の表へ戻すための手掛かりです。元シート名がないと、同じような行を複数の表から探し直す必要があります。

連結後の行番号は、元Excelの行番号と一致しません。西の最初の明細が連結後は三行目でも、元シートではタイトルと見出しの後にあります。教材ではシート名だけを保持しますが、元のセル位置まで必要なら、読み取り時点で元行番号も設計してください。後から連結行番号へ一定値を足す方式は、除外行があると崩れます。

複数のブックを扱う場合には、ファイル名と対象期間も出所に含めます。同じ「東」シートが六月版と七月版にあるなら、シート名だけでは区別できません。どの情報まで必要かを先に決め、業務データそのものを公開用の学習記録へ載せない範囲で記録を残します。

出所の列は、元表に同じ名前がないことも確認してください。元に source_sheet があるのに上書きすると、別の意味で入力された情報が消える可能性があります。今回の列検査では元表を二列に限定しているため衝突しません。汎用処理へ変えるときは、予約する列名を明示する必要があります。

この準備を図にすると、次の流れです。連結の操作は最後の方にあります。読み込みの成功を急ぐより、取り込み範囲と列の意味がそろってからまとめることを重視してください。

  1. 対象シートの存在を確認
  2. 各シートの見出しを指定
  3. 列名を対応させ、列の差を検査
  4. 元シート名と行数を記録
  5. 縦に連結し、件数と合計を照合
列の差が見つかったら、連結へ進む前に理由を確認します。

4行の教材を実行し、結合後の結果を照合する

見出しが違う二枚と、除外する集計表を作る

教材には「東」「西」「集計」の三枚を用意します。東は注文001・002と金額120・80、西は注文003・004と金額200・0です。集計には件数4と金額400を置きます。この集計シートは比較材料であり、明細へ追加しません。西のゼロは未入力ではなく、教材上の明示的な数値0です。

コードはメモリ内へブックを保存して読み直します。作業フォルダーのExcelを上書きしない形なので、練習時の入力ファイルと出力ファイルの取り違えを避けられます。pandasとopenpyxlが利用できる学習環境で実行してください。職場のパソコンへ導入する場合は、勤務先の管理ルールに従ってください。

from io import BytesIO
import pandas as pd
from openpyxl import Workbook

book = Workbook()
east = book.active
east.title = "東"
east.append(["注文ID", "金額"])
east.append(["001", 120])
east.append(["002", 80])
west = book.create_sheet("西")
west.append(["西支店の一覧"])
west.append(["受注番号", "金額(円)"])
west.append(["003", 200])
west.append(["004", 0])
summary = book.create_sheet("集計")
summary.append(["件数", "金額"])
summary.append([4, 400])
buffer = BytesIO()
book.save(buffer)
payload = buffer.getvalue()

注文IDはExcelセルへ文字列として書いています。dtype=object はExcelに保存された値を読み取るための指定で、表示書式から先頭ゼロを復元する機能ではありません。元セルが数値1で表示だけ001なら、本稿と条件が違います。識別子の扱いは先頭ゼロを保つCSV読み込みと併せて、保存されている値から考えましょう。

教材を自分で変更するなら、最初は東の金額120を130へ変え、期待合計410を紙に書いてから実行します。その後、西の見出し行を一行増やして読み取り結果を観察します。値の変更と表の構造の変更を分けると、どの検査が何を見ているのかを理解しやすくなります。

実データを試すときも、最初は一つの支店、少数の行、対象期間を限定した複製で確認します。四件が正しく処理できたことから、多数の帳票で同じ結果になるとは言えません。結合セル、数式、途中の小計、隠れた注記など、教材にない構造があるかを見てから拡張してください。

列検査を通過した表だけを一度に連結する

次のコードは、先ほどの payload の後へ続けて実行します。シート別の設定を spec にまとめ、対象があること、変換後の列が重複していないこと、期待する二列が過不足なくあることを確認します。確認を通過した表だけをリストへ入れ、最後に一度連結します。

required = ["order_id", "amount"]
spec = {
    "東": {"header": 0,
           "rename": {"注文ID": "order_id", "金額": "amount"}},
    "西": {"header": 1,
           "rename": {"受注番号": "order_id", "金額(円)": "amount"}},
}
parts = []
counts = {}
with pd.ExcelFile(BytesIO(payload), engine="openpyxl") as xls:
    absent = set(spec) - set(xls.sheet_names)
    if absent:
        raise ValueError(f"対象シート不足: {sorted(absent)}")
    for name, cfg in spec.items():
        frame = pd.read_excel(xls, sheet_name=name,
                              header=cfg["header"], dtype=object)
        frame.columns = [str(c).strip() for c in frame.columns]
        frame = frame.rename(columns=cfg["rename"])
        if frame.columns.duplicated().any():
            raise ValueError(f"変換後の列名重複: {name}")
        if set(frame.columns) != set(required):
            raise ValueError(f"列の不足・追加: {name}")
        frame = frame.loc[:, required].copy()
        counts[name] = len(frame)
        frame["source_sheet"] = name
        parts.append(frame)
combined = pd.concat(parts, ignore_index=True)
assert len(combined) == sum(counts.values())
print(counts)
print(combined.to_string(index=False))
print("合計:", combined["amount"].sum())

この教材では「東:2、西:2」と表示され、四行が東、東、西、西の順に並びます。注文IDは001から004まで、合計は400です。実行時に列の追加が見つかった場合は、必要な列だけ切り出して続行するのではなく、例外で停止します。追加の意味を確認した後に、期待する列の仕様を修正してください。

assert は教材の照合条件です。実務処理では実行設定によって無効にできるため、運用上止める必要のある検査をassertだけへ依存させないでください。明示的な条件判定と例外、確認結果の記録を組み合わせます。ここでは四行になるという期待を短く示す用途で使っています。

金額の型検査はこのコードへまとめていません。教材は数値だけですが、実帳票に「1,200円」や未入力があれば、合計前に型と意味を調べる工程が必要です。詳しくはpandasでカンマ・円付きの数値を確認する教材を参照してください。列が同じことと、全行が集計可能な値であることは別の条件です。

行数・支店別件数・合計を、それぞれ別に確認する

期待する行数は東二件と西二件の合計四件です。しかし、全体が四件なら十分というわけではありません。東を二度読んで西を読まなくても、全体は四件になり得ます。source_sheet ごとの件数を見て、対象ごとの二件がそろっていることを確かめます。

教材の期待合計は120+80+200+0の400です。西の0が残っていることも確認します。ゼロの行を「空欄のようだから」と除外すると、合計は400のままでも行数は三件になります。合計だけでは、金額ゼロの明細が消えたことを検出できません。

逆に、行数が四件のままでも、金額120を210と読み違えれば合計が変わります。件数と合計は別の性質を確認する指標です。どちらか一つにまとめず、教材では両方を手計算と照合します。さらに注文IDの一覧を確かめると、同じ件数で別の行が入った場合も見つけやすくなります。

教材の照合結果と、見つけられる問題
確認項目今回の期待値見つけたい問題
全体行数4行明細の脱落や集計行の混入
元シートごとの件数東2・西2一方だけの取り込みや二重読込
注文ID001・002・003・004別の対象行が入った可能性
金額合計400値の脱落・集計値の再加算
金額ゼロの明細004の行が残る合計だけでは分からない行の削落

実務では、集計シートの400も誤っているかもしれません。そのため元の集計表との一致だけを最終判断にしません。対象明細から期待値を説明できること、集計表の対象期間や除外条件が同じことを確認します。二つの数字が一致した理由まで考えると、比較材料の使い方が明確になります。

正常な教材に加え、列差で止まる教材も試す

正常に動く例だけでは、検査が問題を見つけられるか分かりません。そこで編集部では、対象へ集計シートを加える条件と、東の二列を両方 amount へ改名する条件も試しました。前者は列の不足・追加、後者は変換後の列名重複として停止しました。これは自作教材のローカル試験です。

自分で練習する場合は、西の「金額(円)」を「売上」に変更してみます。対応表を変えなければ、期待するamountがそろわず止まります。この結果を見てから、売上と金額が本当に同じ定義か考えて対応表を修正します。まずコードを通すために名前を合わせる順序ではありません。

次に、対象にない「説明」シートを追加します。採用リストが東・西のままなら、説明は取り込みません。対象外の追加に影響されないことを確かめられます。ただし、説明に重要な仕様変更が書かれている場合もあるため、実帳票の受領確認まで自動で省略してよいわけではありません。

試験の記録には、変更した条件、期待した結果、実際の結果を残します。「結合できた」だけでなく「列が足りないときに止まった」と書けると、処理の限界を説明できます。勤務先の明細や顧客情報を添付せず、問題を再現する最小の架空データへ置き換えて相談してください。

行数や合計が合わなければ、連結後の表だけを修正する前に、元シートごとの読み取りへ戻ります。headerの位置、採用対象、列名対応、途中小計などを順番に見ます。結果を直接直すと、翌月また同じ原因が現れても分かりません。原因を特定できる単位まで戻すことを学習の到達点にします。

独学・講座を選ぶときは、列の違いを説明できるかで判断する

この四行教材を読み、採用シートと列名対応を自分で変更できるなら、まず独学で別の小さな帳票へ広げられます。逆に、見出しとデータの違い、辞書とDataFrameの違い、例外で止める理由を説明できなければ、Pythonの変数・リスト・条件分岐へ戻る方が学びやすいでしょう。

個別指導を比較する場合、Python Winnerのデータアナリストコースは、公式にpandasを含むPythonデータ分析とコードチェックを掲載しています。2026年10月9日の公式表示では受講料369,600円(税込)、期間4か月、30分のマンツーマンレッスン24回です。これは受講料の表示であり、教材外の費用や契約総額は申込前に確認します。公式コース詳細が根拠です。

検討しやすいのは、Pythonの基礎からデータ分析まで学び、誤った結果の調べ方を人に質問したい人です。単発で一つのExcelだけまとめたい人や、機械学習の開発を主目的とする人は、別の学習範囲も比較したいところです。申込前には、今回のような列差の処理を質問できるか、実務ファイルを渡さず相談できるか、添削対象と追加費用を確認してください。

この教材を講座の実習として受講したわけではありません。公開カリキュラムにpandasがあることから、本稿と同じ処理が授業内で個別に扱われると断定することもできません。「東と西で見出しが違う表の取り込みを説明できるようになりたい」と、自分の目的を具体化して問い合わせます。

広告:【PythonWinner】。学習範囲を比較したいときの入口です。受講や転職の結果を保証するものではありません。詳しい判断材料はPython Winnerの講座と確認事項にまとめています。

よくある質問

Q. sheet_name=Noneにすれば、全シートが一つの表になりますか?
A.

いいえ。シートごとのDataFrameが入った辞書を受け取ります。対象と列の意味を確認してから、必要な表をconcatで連結します。

Q. 列名が違うときはjoin='inner'で解決できますか?
A.

共通列だけを残すため、必要な列を落とすことがあります。意味が同じ列の対応表を作り、列の不足・追加・変換後の重複を確認してから判断します。

Q. ignore_index=Trueで注文IDの重複もなくなりますか?
A.

なくなりません。連結後の行番号を振り直す指定です。注文IDなど業務上の識別子の重複は、別に確認する必要があります。

Q. 合計が合えば、明細の取り込みは正しいですか?
A.

合計だけでは十分ではありません。ゼロの行が消えても合計は変わらないため、対象シート、件数、ID、元シートごとの行数も確認します。

Q. このコードを実務のExcelへそのまま使えますか?
A.

自作の二列教材で確認したコードです。結合セル、数式、小計、取消区分などは扱っていません。元ファイルを上書きせず、実帳票の構造と値の型を確認してから適用範囲を決めてください。

最後に、結合後の表だけを渡すのではなく、対象シート、列名の対応、取り込み件数、除外理由を一緒に説明してみてください。四行の結果を手計算へ戻せること、列が変わったときに止まること、元シートをたどれることが、この練習の結論です。