この記事でわかること

  • 日付の列から、曜日の番号を取り出す方法(dt.day_of_week)
  • 曜日ごとの売上の合計を、月曜から日曜の順に並べて書き出す方法
  • 売上の無い曜日を0の行として残す方法(reindex)
  • 曜日の名前でまとめると並びが崩れる理由と、古い書き方の警告

売上の明細に「曜日」の列を手で足して、曜日ごとの売上を出していませんか。並べ替えると金曜が先頭に来たり、定休日の曜日が表から消えたりすることもあります。この記事では、pandasで日付から曜日を取り出し、月曜から日曜の7行の表にして書き出すまでを順に見ていきます。

参考にしたのは、pandas 3.1.0の公式の資料(Series.dtのday_of_weekとday_name、Series.reindex、DataFrame.groupby、to_datetime)で、2026年10月31日に原文を読みました。明細の日付と金額は、説明のために作った架空のものです。

先に結論: 曜日を番号でまとめ、7行にそろえてから名前を付ける

dt.day_of_weekで曜日を番号(月曜が0、日曜が6)にし、その番号でgroupbyして合計します。 最後にreindexで0から6の7行にそろえ、売上の無い曜日を0で埋めてから、「月」「火」…の名前に置きかえます。

段階 pandasの機能
日付の型にする pd.to_datetime
曜日の番号を取る dt.day_of_week
番号ごとに合計する groupby
月曜から日曜の7行にそろえる reindex

曜日の番号と名前の取り出し方

資料では、day_of_weekは曜日を数で返し、月曜を0、日曜を6とする、と説明しています。週は月曜に始まり、日曜で終わる前提です。

曜日の名前がほしいときはday_nameもあります。ただ、初期の設定では「Monday」のような英語の名前になります。名前のまままとめると並び順の問題が出るので、この記事では番号でまとめ、名前は最後に付けます。

売上の無い曜日を残す(reindex)

groupbyの結果には、明細に出てこない曜日の行がありません。定休日の日曜があると、合計の表は6行になります。

reindexは、渡した並びの行に表をそろえ、元に無かった行は空(NaN)にします。fill_valueを渡すと、空の代わりにその値で埋められます。0から6の番号を渡せば、どの曜日も1行ずつ、月曜から順に並びます。

手順: 売上の明細から曜日ごとの合計を書き出す

次のコードは、架空の明細 daily_sales.xlsx(日付・売上の2列)を読み、曜日ごとの合計を weekday_total.xlsx に書き出します。daily_sales.xlsx には書き込みません。ファイルの名前と列の名前は、手元の明細のものに置きかえて使います。

import pandas as pd

# 売上の明細を読む(元のファイルには書き込まない)
sales = pd.read_excel("daily_sales.xlsx")

# 日付の列を日付の型にする。読めない値は空(NaT)になるので、その数を出しておく
sales["日付"] = pd.to_datetime(sales["日付"], errors="coerce")
print("読めなかった日付の数:", sales["日付"].isna().sum())

# 曜日を番号で取り(月曜が0、日曜が6)、番号ごとに売上を合計する
sales["曜日番号"] = sales["日付"].dt.day_of_week
weekday = sales.groupby("曜日番号")["売上"].sum()

# 月曜から日曜の7行にそろえ、売上の無い曜日は0にしてから名前を付ける
weekday = weekday.reindex(range(7), fill_value=0)
weekday.index = ["月", "火", "水", "木", "金", "土", "日"]
weekday.index.name = "曜日"

print(weekday)
weekday.to_excel("weekday_total.xlsx")

このコードには、pandasのほかに、xlsxのファイルを扱うopenpyxlが要ります。先に入れておきます。

試した結果

2026年10月5日(月)から13日(火)までの売上を入れた、9行の架空の明細で動かしました。日付の1つは「2026/10/07」という文字で入れ、1行は日付の欄に「不明」と書きました。日曜(10月11日)は定休日として行を入れていません。

  • 「読めなかった日付の数: 1」と出ました。「不明」の行です
  • 曜日ごとの合計は、月22,000・火14,000・水9,000・木7,000・金15,000・土20,000・日0の7行で、月曜から順に並びました
  • 文字で入れた「2026/10/07」の行も、水曜の9,000に入りました
  • 「不明」の行の4,000は、どの曜日にも入っていませんでした。明細の合計91,000に対し、7行の合計は87,000です
  • weekday_total.xlsx は、曜日と売上の2列・7行でした
  • 元の daily_sales.xlsx のハッシュ値は、実行の前後で変わりませんでした

動かした環境は、作業用のMacに入れたPython 3.12.15と、pandas 3.1.0、openpyxl 3.1.5です。表をExcelのアプリで開いて見ることはしていません。

自分で直すか、相談するかの判断

目安は、「週を月曜から数えてよいか」と「1日の区切りが0時でよいか」の2つです。どちらもそのままでよければ、上のコードの列の名前を変えるだけで使えます。

日曜始まりで見せたい、深夜0時をまたぐ営業を前の日に数えたい、祝日を分けたい、といった決まりがあるときは、作りが変わります。報告を受け取る人と区切り方を決めてから作り、出した合計は手で数えた週の数字と一度照らし合わせます。

つまずきやすいところ

  • 曜日の名前でまとめる: day_nameの名前でgroupbyすると、試した明細ではFriday・Monday・Saturday…という文字の順になり、月曜から並びませんでした
  • reindexを外す: 試したときも、reindexの行を外すと、合計の表は日曜の無い6行になりました。定休日がある表では、0の行が要るかどうかを先に決めます
  • 日付が文字のまま.dtを使う: to_datetimeで直さずにday_of_weekを使うと、「Can only use .dt accessor」で始まる例外が出て、そこで処理が止まりました。日付の直し方は、PythonでExcelの日付を正しく読み込む手順にまとめています
  • dayofweekと書く: 古い書き方のdayofweekでも番号は同じでしたが、将来の版で消えるという警告が出ました。day_of_weekと書きます
  • 月ごとの合計もほしい: 日付を年月にまとめる方法は、PythonでExcelの日付から月ごとの合計を出す手順で紹介しています
  • 店舗ごと・曜日ごとの表にしたい: 行に店舗、列に曜日を並べる表は、PythonでExcelのピボットテーブルのように集計する手順の方法で作れます

まとめ

  • 日付の列はpd.to_datetimeで直し、読めなかった行の数を確かめます
  • dt.day_of_weekで曜日を番号にしてまとめると、月曜の0から日曜の6の順に並びます
  • reindexで7行にそろえ、売上の無い曜日を0で残してから名前を付けます
  • 古い書き方のdayofweekではなく、day_of_weekと書きます