基礎から学ぶPython入門 90日コース | 業務自動化 - Day 38:pandas集計

Python 90日で身につけるPython
スポンサーリンク
スポンサーリンク

Day 38:pandas集計で「業務レポートを一撃で作る」感覚を身につける

Day 38では、pandasの 集計機能 を使って、 「店舗ごとの売上合計」「商品ごとの平均数量」「件数カウント」など、 業務レポートでよく見る集計表をコードで一気に作ることを目指します。

キーワードは次の5つです。

  • groupby()
  • sum()
  • mean()
  • count()
  • merge()

ここでは、初心者向けにかみ砕いて、 「Excelでピボットテーブルを作るようなことを、pandasでどう書くか」 という視点でステップバイステップで説明していきます。

集計の前提:サンプルデータを用意する

まずは、Day 38で使う売上データをCSVで用意します。

# day38_make_csv.py
def create_sample_csv(filename="sales_day38.csv"):
    """Day 38用のサンプルCSVファイルを作成する関数です。"""
    content = """日付,店舗,商品名,数量,単価,売上
2024-01-01,A,りんご,10,120,1200
2024-01-01,B,みかん,8,100,800
2024-01-01,C,ぶどう,5,300,1500
2024-01-02,A,りんご,7,120,840
2024-01-02,B,みかん,6,100,600
2024-01-02,C,ぶどう,3,300,900
2024-01-03,A,りんご,4,120,480
2024-01-03,B,みかん,9,100,900
2024-01-03,C,ぶどう,2,300,600
"""

    with open(filename, "w", encoding="utf-8") as f:
        f.write(content)

    print(f"{filename} を作成しました。")


if __name__ == "__main__":
    create_sample_csv()
Python

このデータを使って、「店舗ごと」「商品ごと」などの集計を行っていきます。

基本:CSVを読み込んでDataFrameを確認する

import pandas as pd


def load_data():
    """CSVを読み込んで基本情報を確認する例です。"""
    df = pd.read_csv("sales_day38.csv")

    print("=== 読み込んだDataFrame ===")
    print(df)

    print("\n=== 列のデータ型 ===")
    print(df.dtypes)

    return df


if __name__ == "__main__":
    load_data()
Python

ここでのポイントは、

  • pd.read_csv() でCSVをDataFrameとして読み込んでいること。
  • 「店舗」「商品名」「数量」「売上」などの列が揃っていること。

groupby()のイメージ:「同じグループごとにまとめる」

「店舗ごとに売上をまとめる」とは何か

Excelで「店舗ごとの売上合計」を出したいとき、 人間は次のようなことをしています。

  • 店舗Aの行だけを集める
  • 店舗Bの行だけを集める
  • 店舗Cの行だけを集める
  • それぞれの売上を合計する

groupby() は、この「グループ分け」を一気にやってくれる機能です。

店舗ごとの売上合計:groupby() + sum()

import pandas as pd


def groupby_store_sum():
    """店舗ごとの売上合計を計算する例です。"""
    df = pd.read_csv("sales_day38.csv")

    # 店舗ごとに売上を合計します。
    grouped = df.groupby("店舗")["売上"].sum()

    print("=== 店舗ごとの売上合計(Series) ===")
    print(grouped)

    # DataFrameとして表示したい場合は reset_index() を使います。
    result_df = grouped.reset_index()

    print("\n=== 店舗ごとの売上合計(DataFrame) ===")
    print(result_df)


if __name__ == "__main__":
    groupby_store_sum()
Python

ここでの重要ポイントは、

  • df.groupby("店舗") で「店舗ごと」にグループ分けしていること。
  • ["売上"].sum() で、各グループの売上合計を計算していること。
  • reset_index() で「店舗」と「売上合計」の2列からなるDataFrameに整形していること。

商品ごとの平均数量:groupby() + mean()

import pandas as pd


def groupby_product_mean():
    """商品ごとの平均数量を計算する例です。"""
    df = pd.read_csv("sales_day38.csv")

    # 商品名ごとに数量の平均を計算します。
    grouped = df.groupby("商品名")["数量"].mean()

    print("=== 商品ごとの平均数量(Series) ===")
    print(grouped)

    result_df = grouped.reset_index()
    result_df.rename(columns={"数量": "平均数量"}, inplace=True)

    print("\n=== 商品ごとの平均数量(DataFrame) ===")
    print(result_df)


if __name__ == "__main__":
    groupby_product_mean()
Python

ポイント:

  • mean() で平均値を計算していること。
  • rename() で列名を「平均数量」に変えて、分かりやすくしていること。

店舗ごとの件数:groupby() + count()

「何件の売上があったか」を数える

import pandas as pd


def groupby_store_count():
    """店舗ごとの売上件数を数える例です。"""
    df = pd.read_csv("sales_day38.csv")

    # 店舗ごとに「行数(件数)」を数えます。
    grouped = df.groupby("店舗")["売上"].count()

    print("=== 店舗ごとの売上件数(Series) ===")
    print(grouped)

    result_df = grouped.reset_index()
    result_df.rename(columns={"売上": "件数"}, inplace=True)

    print("\n=== 店舗ごとの売上件数(DataFrame) ===")
    print(result_df)


if __name__ == "__main__":
    groupby_store_count()
Python

ここでのポイントは、

  • count() が「非欠損値の件数」を数える関数であること。
  • 「売上列の件数」を数えることで、「その店舗で何件の売上が記録されているか」を把握できること。

複数列を一度に集計する:agg()

店舗ごとに「売上合計」と「平均数量」を同時に出す

import pandas as pd


def groupby_multiple_agg():
    """店舗ごとに複数の集計を同時に行う例です。"""
    df = pd.read_csv("sales_day38.csv")

    grouped = df.groupby("店舗").agg({
        "売上": "sum",   # 売上合計
        "数量": "mean",  # 平均数量
    })

    print("=== 店舗ごとの売上合計・平均数量 ===")
    print(grouped)

    result_df = grouped.reset_index()
    result_df.rename(columns={"売上": "売上合計", "数量": "平均数量"}, inplace=True)

    print("\n=== 整形後のDataFrame ===")
    print(result_df)


if __name__ == "__main__":
    groupby_multiple_agg()
Python

ポイント:

  • agg() に辞書を渡すことで、「列ごとにどの集計関数を使うか」を指定できること。
  • 一度の groupby() で複数の集計結果を出せるため、効率が良いこと。

merge()のイメージ:「別の表をくっつける」

「マスタ情報」と「売上データ」を結合する

業務では、次のような構成がよくあります。

  • 売上データ:店舗コード・商品コード・数量・売上
  • マスタデータ:店舗コードと店舗名、商品コードと商品名

このとき、コードだけでは分かりにくいので、名前をくっつけたい という場面が出てきます。 merge() は、この「別の表をくっつける」ための機能です。

店舗マスタと売上データをmergeする

店舗マスタを作る

# day38_make_store_master.py
def create_store_master(filename="store_master.csv"):
    """店舗マスタCSVを作成する関数です。"""
    content = """店舗コード,店舗名
A,東京店
B,大阪店
C,名古屋店
"""

    with open(filename, "w", encoding="utf-8") as f:
        f.write(content)

    print(f"{filename} を作成しました。")


if __name__ == "__main__":
    create_store_master()
Python

売上データと店舗マスタを結合する

import pandas as pd


def merge_store_master():
    """売上データと店舗マスタを結合する例です。"""
    df_sales = pd.read_csv("sales_day38.csv")
    df_store = pd.read_csv("store_master.csv")

    # 売上データの「店舗」列と、店舗マスタの「店舗コード」列を結合します。
    merged = pd.merge(
        df_sales,
        df_store,
        left_on="店舗",       # 売上データ側のキー
        right_on="店舗コード"  # マスタ側のキー
    )

    print("=== 結合後のDataFrame ===")
    print(merged)


if __name__ == "__main__":
    merge_store_master()
Python

ここでの重要ポイントは、

  • pd.merge() で2つのDataFrameを結合していること。
  • left_onright_on で「どの列同士をキーにするか」を指定していること。
  • 結合後のDataFrameに「店舗名」が追加され、レポートとして分かりやすくなること。

merge後にgroupbyで集計する流れ

「店舗名ごとの売上合計」を出す

import pandas as pd


def merge_and_groupby():
    """店舗名を付けてから店舗ごとの売上合計を集計する例です。"""
    df_sales = pd.read_csv("sales_day38.csv")
    df_store = pd.read_csv("store_master.csv")

    merged = pd.merge(
        df_sales,
        df_store,
        left_on="店舗",
        right_on="店舗コード"
    )

    # 店舗名ごとに売上合計を計算します。
    grouped = merged.groupby("店舗名")["売上"].sum()

    result_df = grouped.reset_index()
    result_df.rename(columns={"売上": "売上合計"}, inplace=True)

    print("=== 店舗名ごとの売上合計 ===")
    print(result_df)


if __name__ == "__main__":
    merge_and_groupby()
Python

ポイント:

  • merge() で「店舗名」を付けてから groupby() することで、 「東京店」「大阪店」「名古屋店」といった分かりやすい集計表になること。

Day 38ミニテンプレート:pandas集計まとめスクリプト

最後に、Day 38で扱った要素を一通り試せるテンプレートを示します。

# day38_pandas_aggregate.py
import pandas as pd


def load_sales(filename="sales_day38.csv"):
    df = pd.read_csv(filename)
    print("=== 売上データ ===")
    print(df)
    return df


def load_store_master(filename="store_master.csv"):
    df = pd.read_csv(filename)
    print("=== 店舗マスタ ===")
    print(df)
    return df


def aggregate_examples(df_sales):
    # 店舗ごとの売上合計
    store_sum = df_sales.groupby("店舗")["売上"].sum().reset_index()
    store_sum.rename(columns={"売上": "売上合計"}, inplace=True)
    print("\n=== 店舗ごとの売上合計 ===")
    print(store_sum)

    # 商品ごとの平均数量
    product_mean = df_sales.groupby("商品名")["数量"].mean().reset_index()
    product_mean.rename(columns={"数量": "平均数量"}, inplace=True)
    print("\n=== 商品ごとの平均数量 ===")
    print(product_mean)

    # 店舗ごとの件数
    store_count = df_sales.groupby("店舗")["売上"].count().reset_index()
    store_count.rename(columns={"売上": "件数"}, inplace=True)
    print("\n=== 店舗ごとの売上件数 ===")
    print(store_count)


def merge_and_aggregate(df_sales, df_store):
    merged = pd.merge(
        df_sales,
        df_store,
        left_on="店舗",
        right_on="店舗コード"
    )

    print("\n=== 結合後のDataFrame ===")
    print(merged)

    store_name_sum = merged.groupby("店舗名")["売上"].sum().reset_index()
    store_name_sum.rename(columns={"売上": "売上合計"}, inplace=True)

    print("\n=== 店舗名ごとの売上合計 ===")
    print(store_name_sum)


def main():
    df_sales = load_sales()
    df_store = load_store_master()

    aggregate_examples(df_sales)
    merge_and_aggregate(df_sales, df_store)


if __name__ == "__main__":
    main()
Python

Day 38のまとめ

Day 38では、pandas集計として、

  • groupby() で「店舗ごと」「商品ごと」にデータをグループ分けする考え方
  • sum()mean()count() を使って、合計・平均・件数を簡単に計算する方法
  • agg() で複数の集計を一度に行う方法
  • merge() で「売上データ」と「店舗マスタ」を結合し、分かりやすいレポートにする方法
  • 結合後に groupby() することで、「店舗名ごとの売上合計」などの実務的な集計表を作る流れ

をステップバイステップで体験していただきました。

ここまで来ると、pandasを使って 「業務レポートを自動生成する」 というイメージがかなり具体的になっているはずです。 次のステップでは、さらに高度な集計や可視化に進み、 データから「気づき」を得るところまで広げていくことができます。

タイトルとURLをコピーしました