Excelで複数年の15分刻みデータを年を無視して月別平均・最小・最大に集計する方法

複数年にまたがる15分刻みの時系列データを、年を無視して「1〜12月」だけで平均・最小・最大に集計したい。そんなときは、日時から“月”だけを取り出して条件判定するのが最短ルートです。数式だけで完結させる定番パターンを、実務目線で整理します。

目次

複数年×15分刻みデータで「月別(年は無視)」集計が難しく感じる理由

15分刻みのログは、1日あたり96点(24時間×4)あります。これが複数年分になると、数万〜数十万行の規模になることも珍しくありません。たとえば5年分なら、概算で 96×365×5≒175,200行。この規模で「年は無視して1月だけ平均」などをやろうとすると、やり方次第で計算が重くなったり、集計条件が意図とズレたりします。

よくあるつまずきが、AVERAGEIFSで日付範囲を指定してしまうケースです。

なぜ AVERAGEIFS だと「年を無視した月別集計」がやりにくいのか

AVERAGEIFS は「条件範囲(セル範囲)に対して、条件(文字列や値)を当てる」関数です。ところが、年を無視するために必要な条件は「日時の“月”だけを見たい」なので、単純な日付範囲(1/1〜2/1)では年が必ず混ざります。

やりがちな指定起きることなぜズレる?
「2025/1/1〜2025/2/1」で平均“2025年の1月”だけ集計される開始・終了日が年を固定してしまうため
「1月」をワイルドカードのように指定したいAVERAGEIFS単体では難しい条件範囲に MONTH(A:A) のような式を直接渡せない(基本はセル範囲が前提)

そこで発想を切り替えます。日付から“月番号(1〜12)”だけ取り出して、その月番号で集計すれば、年の情報は自然に無視できます。

結論:MONTH関数で「月」だけを取り出して条件判定する

Excelの日付時刻は内部的には連続した数値(シリアル値)で、表示は「yyyy/mm/dd hh:mm」でも、MONTH() は 月だけ(1〜12)を返します。

つまり、条件を次の形にできれば勝ちです。

  • 条件:MONTH(日時)=1(1月)
  • 集計対象:その行の値(例:列B)

先に作っておくと速い:月別集計の「受け皿」テンプレ

数式をコピペして運用しやすい形として、まず集計表を作ります。たとえば以下のように「月番号」と「平均・最小・最大」を並べると、12か月分が一気に作れます。

列見出し例内容入力例
D月月番号(1〜12)D2に1、D3に2…D13に12
E平均その月の平均値E2に平均式、下へコピー
F最小その月の最小値F2に最小式、下へコピー
G最大その月の最大値G2に最大式、下へコピー
H(任意)件数その月のデータ件数(チェック用)H2に件数式、下へコピー

以降の式は「データが Dataシート にあり、A列=日時、B列=値、範囲は2行目〜5000行目」という例で書きます(実データに合わせて調整してください)。

方法:どのExcelでも通しやすい王道(配列数式 or IF配列)

最も定番なのは、MONTH() の結果で条件を作り、条件に合う値だけを AVERAGE / MIN / MAX に渡す方法です。これで「年」は自然に無視されます。

平均(例:1月)

古いExcelでは配列数式として確定(必要なら Ctrl+Shift+Enter)。Microsoft 365などの動的配列対応環境なら、通常のEnterで動きます。

=AVERAGE(IF(MONTH(Data!$A$2:$A$5000)=1, Data!$B$2:$B$5000))

最小/最大(同パターン)

=MIN(IF(MONTH(Data!$A$2:$A$5000)=1, Data!$B$2:$B$5000))
=MAX(IF(MONTH(Data!$A$2:$A$5000)=1, Data!$B$2:$B$5000))

ここで「1」を「2(2月)」「3(3月)」…に変えれば各月に対応できます。先ほどのテンプレ通り、月番号をD列に置いて参照する形にしておくと、コピー運用が非常に楽になります。

月番号をセル参照にして12か月分を量産する

たとえば D2 に月番号(1〜12)が入っているなら、式はこうなります。

=AVERAGE(IF(MONTH(Data!$A$2:$A$5000)=D2, Data!$B$2:$B$5000))
=MIN(IF(MONTH(Data!$A$2:$A$5000)=D2, Data!$B$2:$B$5000))
=MAX(IF(MONTH(Data!$A$2:$A$5000)=D2, Data!$B$2:$B$5000))

実務でつまずきやすい「空白・エラー」を避ける強化版

ログには空白やエラー値(#N/Aなど)が混ざることがあります。月別集計を安定させたいなら、条件に ISNUMBER を足して「数値だけ集計」すると事故が減ります。

=AVERAGE(IF((MONTH(Data!$A$2:$A$5000)=D2)*(ISNUMBER(Data!$B$2:$B$5000)), Data!$B$2:$B$5000))

=MIN(IF((MONTH(Data!$A$2:$A$5000)=D2)*(ISNUMBER(Data!$B$2:$B$5000)), Data!$B$2:$B$5000))

=MAX(IF((MONTH(Data!$A$2:$A$5000)=D2)*(ISNUMBER(Data!$B$2:$B$5000)), Data!$B$2:$B$5000))

15分刻みのデータは量が多いぶん、「エラーが混ざっていて結果が全部止まる」が最も痛いので、この強化版はかなりおすすめです。

範囲は「列全体」ではなく、現実的な範囲に絞る

配列計算で A:A や B:B のように列全体を指定すると、データが増えるほど(またはPC環境によっては増えなくても)計算が重くなりがちです。$A$2:$A$5000 のように、まずは現実的な最大行まで絞っておくのが安定します。

方法:平均だけなら SUMPRODUCT で配列確定を回避できる

「配列数式の確定が面倒」「他の人が編集すると壊れがち」という場合、平均は SUMPRODUCT を使うと回避できます。条件に合う値の合計を、条件に合う件数で割るイメージです。

SUMPRODUCT版(平均)

=SUMPRODUCT((MONTH(Data!$A$2:$A$5000)=D2)*Data!$B$2:$B$5000)
/SUMPRODUCT(--(MONTH(Data!$A$2:$A$5000)=D2))

ただし、一般に 最小/最大はSUMPRODUCTだけで置き換えにくいため、最小最大は配列パターン、または次の「FILTER」や「AGGREGATE」を使う方が楽です。

SUMPRODUCTを実務仕様にする(空白やエラーを除外)

値の列に空白やエラーがあり得るなら、数値だけを集計対象にするとより安全です(条件を掛け合わせます)。

=SUMPRODUCT((MONTH(Data!$A$2:$A$5000)=D2)*(ISNUMBER(Data!$B$2:$B$5000))*Data!$B$2:$B$5000)
/SUMPRODUCT((MONTH(Data!$A$2:$A$5000)=D2)*(ISNUMBER(Data!$B$2:$B$5000)))

最小/最大を「配列確定なし」でやりたい場合の選択肢(AGGREGATE)

環境によっては配列確定を避けたいことがあります。その場合、AGGREGATE を使うと「条件に合わない行をエラー化して無視する」という形で最小・最大を取りにいけます。

以下は 一致しない行(または空白)を割り算でエラーにして除外する考え方です。HTML上で数式が崩れないよう、<> はエスケープしています。

=AGGREGATE(15,6,Data!$B$2:$B$5000/((MONTH(Data!$A$2:$A$5000)=D2)*(Data!$B$2:$B$5000<>"")),1)

=AGGREGATE(14,6,Data!$B$2:$B$5000/((MONTH(Data!$A$2:$A$5000)=D2)*(Data!$B$2:$B$5000<>"")),1)
  • 15 は SMALL(小さい順)なので 最小 を取れます(k=1)
  • 14 は LARGE(大きい順)なので 最大 を取れます(k=1)
  • 6 は「エラー値を無視」オプションです

データ量が多いときに、環境差で配列確定が扱いにくい場合の逃げ道として覚えておくと便利です。

方法:Excel 365なら FILTER がいちばんシンプル(平均/最小/最大が同じ形)

Microsoft 365(動的配列)環境なら、FILTER で「その月の値だけを抽出」してから集計できるので、式が読みやすく、最小最大も同じ形で書けます。

FILTER版(D2に月番号がある想定)

=AVERAGE(FILTER(Data!$B$2:$B$5000, MONTH(Data!$A$2:$A$5000)=D2))
=MIN(FILTER(Data!$B$2:$B$5000, MONTH(Data!$A$2:$A$5000)=D2))
=MAX(FILTER(Data!$B$2:$B$5000, MONTH(Data!$A$2:$A$5000)=D2))

その月にデータが無いとき(#CALC!)の対策

まれに「一部の月だけ欠損」しているデータもあります。FILTER は抽出結果が0件だとエラーになりやすいので、公開用の集計表なら IFERROR で表示を整えると親切です。

=IFERROR(AVERAGE(FILTER(Data!$B$2:$B$5000, MONTH(Data!$A$2:$A$5000)=D2)),"")
=IFERROR(MIN(FILTER(Data!$B$2:$B$5000, MONTH(Data!$A$2:$A$5000)=D2)),"")
=IFERROR(MAX(FILTER(Data!$B$2:$B$5000, MONTH(Data!$A$2:$A$5000)=D2)),"")

空白にしたくない場合は「0」や「該当なし」など運用に合わせて変更してください。

方法:Excel 365で「12か月分を一気に表で出す」(LET + SEQUENCE + MAP/HSTACK)

月ごとに式をコピーするのも十分実務的ですが、Microsoft 365なら1つの数式で12か月分の集計表を自動生成できます。月別平均・最小・最大をまとめて出すと、シートがスッキリし、更新漏れも減ります。

月番号(1〜12)+平均+最小+最大を一括生成する例

=LET(
  dt, Data!$A$2:$A$5000,
  v,  Data!$B$2:$B$5000,
  m,  SEQUENCE(12),
  HSTACK(
    m,
    MAP(m, LAMBDA(mm, IFERROR(AVERAGE(FILTER(v, MONTH(dt)=mm)), ""))),
    MAP(m, LAMBDA(mm, IFERROR(MIN(FILTER(v, MONTH(dt)=mm)), ""))),
    MAP(m, LAMBDA(mm, IFERROR(MAX(FILTER(v, MONTH(dt)=mm)), "")))
  )
)

出力は「1〜12の月番号」と、各月の平均・最小・最大が横に並んだ表になります。見出しが欲しければ、別セルに見出し行を用意するか、VSTACK でヘッダーを足す形にします。

「月番号」ではなく「1月、2月…」表示にしたい場合

月番号を表示しておいても問題ありませんが、レポート用途なら「1月」表示の方が直感的です。TEXT と DATE を使って、年はダミー(たとえば2000年)で月だけ表示にします。

=LET(
  dt, Data!$A$2:$A$5000,
  v,  Data!$B$2:$B$5000,
  m,  SEQUENCE(12),
  label, TEXT(DATE(2000,m,1),"m""月"""),
  HSTACK(
    label,
    MAP(m, LAMBDA(mm, IFERROR(AVERAGE(FILTER(v, MONTH(dt)=mm)), ""))),
    MAP(m, LAMBDA(mm, IFERROR(MIN(FILTER(v, MONTH(dt)=mm)), ""))),
    MAP(m, LAMBDA(mm, IFERROR(MAX(FILTER(v, MONTH(dt)=mm)), "")))
  )
)

「年は無視して月だけ見たい」集計と相性が良く、見た目もわかりやすくなります。

方法:GROUPBYが使える環境なら、月別集計を“まとめて”返す発想もある

GROUPBY は、指定したキーでグループ化して集計するための新しめの関数群(提供状況は環境差があることがあります)で、月別集計の考え方と相性が良いです。ポイントは、キーを MONTH(日時) にすること。

ただし、関数の引数構成や利用可否は配信チャネル・更新状況で差が出る場合があるため、まずはExcelの数式入力中に表示されるヘルプ(引数ガイド)で確認してください。もし使えない環境なら、本記事の FILTER または LET+MAP の方法がそのまま代替になります。

やりたいこと安定して使えるおすすめMicrosoft 365でのおすすめ
月別の平均だけ欲しいSUMPRODUCTFILTER または LET+MAP
月別の平均・最小・最大が欲しいIF配列(平均/最小/最大)FILTER(平均/最小/最大)または LET+MAP 一括表
月別一覧を自動生成して表で出したいIF配列+テンプレ表LET+SEQUENCE+MAP/HSTACK(1式で12か月)

よくある失敗とチェックポイント(結果が変・エラーになる)

月別集計はシンプルに見えますが、「日時が文字列だった」「値に空白やエラーが混ざった」などで結果が崩れがちです。ありがちな症状と対策をまとめます。

症状原因対策
MONTHが期待通りに判定されない日時が“文字列”として入っている(見た目は日付でも内部がテキスト)日付に変換(VALUE、日付の区切り位置、Power Queryなど)。まずはセルの表示形式ではなく「中身」を疑う
AVERAGEが #DIV/0! になる該当月の件数が0IFERRORで空白表示、または件数(COUNT)を併記して欠損月を把握
MIN/MAXが #VALUE! になる値の列にエラー値が混在ISNUMBER条件を追加、またはFILTERで数値だけ抽出してから集計
集計がやけに遅い列全体参照、過剰な配列計算、揮発性関数の多用範囲を絞る/テーブル化(Ctrl+T)/必要なら集計シートと入力シートを分ける
月別平均が直感と合わない空白が多い、0の意味が「欠測」なのか「実測0」なのか混ざっている欠測は空白にする運用に寄せる、または欠測判定列を作る(どうしても必要なら補助列も検討)

データ量が多いほど効く:重くしないための実務テクニック

15分刻みデータは「月別集計くらいなら軽いはず」と思いがちですが、配列計算が絡むと一気に重くなります。現場で効く対策をまとめます。

テクニック狙い具体例
範囲を絞る配列計算の対象を減らす$A$2:$A$5000 のように最大行を決める(列全体参照を避ける)
テーブル化(Ctrl+T)範囲伸長に自動追従し、参照の管理を楽にするDataテーブルの列を Data[日時], Data[値] のように参照
「月番号」をセルに置く式の再利用性を上げるMONTH(...)=D2 にして下へコピー
数値以外を先に除外エラー停止を避ける条件に ISNUMBER(値) を追加して集計
集計は“別シート”でまとめる編集ミス・参照崩れを減らす入力データは触らず、集計シートで式を管理

応用:月別だけでなく「月×時刻(15分)」で平均を出したいとき

月別平均が作れるようになると、次に出てきがちなのが「1月の0:00、1月の0:15…のように、月×時刻で平均を出したい」という要件です。電力・温湿度・生産設備の稼働率など、日内変動を月別に見たいときに便利です。

この場合はキーを2つ作ります。

  • 月キー:MONTH(日時)
  • 時刻キー:MOD(日時,1)(日付部分を捨てて時刻だけ取り出す)

数式だけでやるなら少し高度になりますが、発想は同じです。「年や日付を捨てて、見たい粒度のキー(月・時刻)だけで集計する」。この考え方を押さえておくと、15分刻みデータの分析が一気にやりやすくなります。

まとめ:年を無視した月別集計は「MONTHで条件化」が最短

複数年の時系列データを「年は無視して月別に平均・最小・最大を出す」なら、やることはシンプルです。日時から月番号だけを取り出し、その月番号で条件判定して集計する。これだけで、AVERAGEIFSの「年固定」問題を回避できます。

環境やデータの状態(空白・エラー・欠損・行数)に合わせて、次のどれかを選ぶのが実務的です。

  • どのExcelでも堅実:IF配列(AVERAGE/MIN/MAX)
  • 平均だけ手早く:SUMPRODUCT
  • Microsoft 365で読みやすく:FILTER
  • 12か月分を自動表化:LET+SEQUENCE+MAP/HSTACK

まずは「月番号をセルに置いて、式を下へコピー」から始め、必要に応じて一括出力の形に進化させるのがスムーズです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次