pandas の集計機能は SQL の GROUP BY に似ていますが、より柔軟です。「銘柄ごと」「月ごと」「曜日ごと」のような切り口でデータを束ねて、平均・合計・標準偏差などの統計量を一気に算出できます。

本記事では、groupby / agg / pivot_table の 3 つを軸に、株価データに対する典型的な集計パターンを順に確認します。

目次

  1. インストール
  2. サンプルデータの準備
  3. groupby の基本
  4. agg で複数の集計を同時に
  5. transform で「グループ集計値を行に戻す」
  6. 月次・週次に集計する
  7. pivot_table でクロス集計
  8. groupby と並べ替えの注意点

インストール

Terminal window
pip install pandas

検証バージョン: Python 3.12.5 / pandas 2.2.3

サンプルデータの準備

複数銘柄・複数日のサンプルデータを作ります。

import pandas as pd
data = {
"Date": [
"2026-04-01", "2026-04-02", "2026-04-03", "2026-04-04", "2026-04-05",
"2026-04-01", "2026-04-02", "2026-04-03", "2026-04-04", "2026-04-05",
"2026-04-01", "2026-04-02", "2026-04-03", "2026-04-04", "2026-04-05",
],
"Code": [
7203, 7203, 7203, 7203, 7203,
9984, 9984, 9984, 9984, 9984,
8306, 8306, 8306, 8306, 8306,
],
"C": [
2900, 2925, 2880, 2910, 2945,
9800, 9750, 9900, 9850, 9820,
1450, 1448, 1462, 1470, 1480,
],
"Vo": [
11_000_000, 9_500_000, 12_500_000, 10_200_000, 9_800_000,
4_200_000, 5_100_000, 4_800_000, 3_900_000, 4_400_000,
18_000_000, 17_500_000, 19_200_000, 18_800_000, 17_900_000,
],
}
df = pd.DataFrame(data)
df["Date"] = pd.to_datetime(df["Date"])
print(df.head())

Date は datetime 型に変換しておきます。後段の月次集計で必要になります。

groupby の基本

「銘柄ごとの平均終値」を計算します。

mean_close = df.groupby("Code")["C"].mean()
print(mean_close)
Code
7203 2912.0
8306 1462.0
9984 9824.0
Name: C, dtype: float64

groupby("Code") で「Code 列の値が同じ行」をグループにまとめ、["C"] で対象列を絞り、.mean() で集計します。「分けて → 計算 → 戻す」が groupby の基本パターンです。

複数列をまとめて集計したいときは、列を選ばずに集計関数を呼びます。

grouped = df.groupby("Code")[["C", "Vo"]].mean()
print(grouped)

agg で複数の集計を同時に

1 つの列に対して複数の統計量を、列ごとに違う関数を、まとめて指定できます。

summary = df.groupby("Code").agg(
mean_close=("C", "mean"),
max_close=("C", "max"),
min_close=("C", "min"),
sum_volume=("Vo", "sum"),
)
print(summary)
mean_close max_close min_close sum_volume
Code
7203 2912.0 2945 2880 53000000
8306 1462.0 1480 1448 91400000
9984 9824.0 9900 9750 22400000

新しい列名=("対象列", "集計関数") の形式が pandas 1.0 系以降の推奨書式です。可読性が高く、どの列がどの集計か一目で分かります。

集計関数には文字列だけでなく、自作のラムダや関数も渡せます。

def range_(s):
return s.max() - s.min()
stats = df.groupby("Code").agg(
daily_range=("C", range_),
std_close=("C", lambda s: s.std(ddof=1)),
)
print(stats)

transform で「グループ集計値を行に戻す」

groupby().mean() は行数が減りますが、transform を使うと 元の行数を保ったまま グループの集計値を各行に貼り付けられます。

df["mean_close_by_ticker"] = df.groupby("Code")["C"].transform("mean")
df["close_dev"] = df["C"] - df["mean_close_by_ticker"]
print(df.head())

「銘柄平均からの乖離」「銘柄ごとの累積リターン」のように、行ごとの計算で集計値が必要な場面で使います。

月次・週次に集計する

日付列をインデックスにして resample を使うと、時間軸での再集計ができます。

df_indexed = df.set_index("Date")
monthly = (
df_indexed.groupby("Code")["C"]
.resample("ME")
.mean()
)
print(monthly)

"ME" は月末(Month End)、"W" は週末、"D" は日次です。サンプルでは 1 ヶ月分しかないため値は 1 行ずつですが、長期データで威力を発揮します。時系列の詳細は#4-4「pandas で時系列を扱う」 で扱います。

pivot_table でクロス集計

pivot_table は「行」「列」「値」の 3 軸でクロス集計を作ります。Excel のピボットテーブルと同じ発想です。

pv = df.pivot_table(
index="Date",
columns="Code",
values="C",
aggfunc="mean",
)
print(pv)
Code 7203 8306 9984
Date
2026-04-01 2900.0 1450.0 9800.0
2026-04-02 2925.0 1448.0 9750.0
2026-04-03 2880.0 1462.0 9900.0
2026-04-04 2910.0 1470.0 9850.0
2026-04-05 2945.0 1480.0 9820.0

「銘柄を列に展開した日次価格表」になります。これは ワイド形式 と呼ばれ、銘柄間の相関や複数銘柄チャートを描くときに使いやすい形です。

逆方向(ワイド → ロング)への変換は pd.melt です。#4-5「pandas でデータを結合する」 で扱います。

groupby と並べ替えの注意点

groupby はデフォルトでグループキーをソートします。順序を保ちたいときは sort=False を指定します。

df.groupby("Code", sort=False)["C"].mean()

また、グループキーを インデックスに含めたくない ときは as_index=False を使うと、結果が通常の DataFrame になります。

df.groupby("Code", as_index=False)["C"].mean()

生成AI へのプロンプト例

集計の意図を生成AI に伝えるときは、入力列・集計軸・出力形式を明確に書きます。

pandas DataFrame に対して次の集計を行うコードを書いてください。
入力:
- df(列: Date, Code, C, Vo)
- Date は datetime64
要件:
- 銘柄ごとに次の値を計算する
- 期間中の単純リターン(末日 / 初日 - 1)
- 期間中の標準偏差(ddof=1)
- 期間中の最大ドローダウン(累積リターンの高値からの最大下落率)
- 結果は Code をインデックスに持つ DataFrame
- pandas 2.2 系で、agg と transform を使い分ける

「列名」「型」「集計の定義」を順に書くと、再現性のあるコードが返ります。

まとめ

  • groupby + agg で「銘柄ごと・期間ごと」の集計を 1 行で書ける
  • agg(新列名=("元列", "関数")) は推奨書式で可読性が高い
  • transform は集計値を 各行に戻す 操作で、乖離・標準化に便利
  • pivot_table でロング形式 → ワイド形式のクロス集計ができる
  • 月次・週次への再集計は resample を使う(時系列は#4-4「pandas で時系列を扱う」)