「Python in Excel」で自作関数を登録|アンピボット関数と計算順序
クロス集計表(マトリクス表)をリスト形式(縦持ちデータ)に変換するアンピボット処理。
Python in Excel(=PY)を使えば、汎用的なアンピボット関数を1つ定義しておくだけで、ブック内の複数の場所から呼び出して使い回せるようになります。
変換イメージ
【変換前:クロス集計表】

【変換後:アンピボット(縦持ちのデータ)】

「Python in Excel」でアンピボット
r, c, v = xl("A3:B6").values, xl("C1:F2").T.values, xl("C3:F6").values
pd.DataFrame([[*rv, *cv, val] for rv, row in zip(r, v) for cv, val in zip(c, row)])
※コードの詳細解説は後程、関数化した後に掲載します。
しかし、この単体コードのまま運用しようとすると、実務では以下のような課題に直面します。
- コードのコピペ・二重管理が発生する(DRY原則の違反)
別のシートや別のセル範囲でアンピボットを行うたびに、同じPythonコードをコピー&ペーストして範囲指定を書き換える必要があります。
もし処理ロジックに変更や修正が生じた場合、ブック内に散らばったすべてのPythonセルを1つずつ修正して回らなければなりません。
- 数式バーの可読性が低下する
データを出力したいセルの中に複雑な内包表記や zip() などのロジックが直接書かれていると、数式バーがコードで埋まり、「そのセルが何を実行しているのか」がパッと見て直感的に分かりにくくなります。
- 利用者に高度なPython知識を求めてしまう
作成者以外のユーザーがそのブックを使う際、コード内部の処理構造(zip や転置 .T)を理解していないと、範囲の変更すら怖くて触れないという状態に陥りがちです。
関数化しておくことで、以下のような大きなメリットが得られます。
- 呼び出し側が unpivot(...) の1行で完結する
集計や分析を行うセルには、標準のExcel関数と同じ感覚で unpivot(行ヘッダー, 列ヘッダー, データ値) と指定するだけで済み、数式バーが非常にすっきりします。
- ロジックとデータの完全分離
「アンピボットの処理手順」は定義シートの1箇所に集約され、「どの範囲を変換するか」だけを各呼び出しセルが担うため、保守性・メンテナンス性が大幅に向上します。
- ブック全体の「共通部品」として再利用できる
1度登録しておけば、同じブック内のどのシート・どのセルからでも、コードを再記述することなく何度でも呼び出して使い回せます。
アンピボット関数の定義と呼び出し
Python関数の定義
def unpivot(r, c, v):
return pd.DataFrame([[*rv, *cv, val] for rv, row in zip(r.values, v.values) for cv, val in zip(c.T.values, row)])
同一シートでこの関数を使う場合は、
Python関数の呼び出し
unpivot(xl("A3:B6"), xl("C1:F2"), xl("C3:F6"))| 引数 | 指定する範囲 | 役割・内容 |
| r | A3:B6 | 行ヘッダー(例: 地域、店舗など) |
| c | C1:F2 | 列ヘッダー(例: 年度、期など) |
| v | C3:F6 | データ本体(例: 売上高、数値データ) |

PY関数の入力






Pythonコード構造の解説
各要素の役割から内部の処理手順、この書き方を採用するメリットまで詳しく見ていきます。
- .values でセル範囲を二次元配列として扱う
xl("A3:B6") で取得したオブジェクトは Pandas の DataFrame です。
インデックスや列名を意識せず、セルに入っている「値」だけを二次元配列として扱うために .values を利用しています。 - .T で列ヘッダーを転置する
列ヘッダー c(C1:F2)は 2行 × 4列 のデータ構造です。
このままでは列ごとの属性(例: ['2025年度', '上期'])を1つの単位として取り出せません。
そこで c.T を使って 転置(行列の入れ替え) を行い、4行 × 2列 の形に変換します。これにより、c.T.values をループ処理した際に、列ごとのヘッダー情報を1つの塊として取得できるようになります。 - zip() で行ヘッダーとデータを対応させる
zip(r.values, v.values) を使うことで、1行分の行ヘッダー(rv)と、対応する1行分のデータ群(row)をペアとして同時に抽出します。
rv: ['関東', '東京店']row: [1200, 1500, 1300, 1600] - zip() で列ヘッダーとデータ値を対応させる
内側のループで zip(c.T.values, row) を実行し、転置した列ヘッダーと個別データ値を1つずつ対応させます。
cv: ['2025年度', '上期']val: 1200 - *(アンパック演算子)でリストを平坦化する
各ループで得られた要素を [*rv, *cv, val] の形で結合します。
*(アンパック演算子)を使うことで、ネストされたリストを展開し、['関東', '東京店', '2025年度', '上期', 1200] という1次元のフラットなリストを作成します。
最後に全体を pd.DataFrame(...) に渡すことで、整列された縦持ちのデータフレームが完成します。
Python# 内包表記を使わずに書いた同等の処理
# 内包表記を使わずに書いた同等の処理
data = []
for rv, row in zip(r.values, v.values): # 【外側ループ】行方向のスキャン(4回)
for cv, val in zip(c.T.values, row): # 【内側ループ】列方向のスキャン(4回)
data.append([*rv, *cv, val]) # 1行分の要素を結合して追加
return pd.DataFrame(data)- 外側ループ: 行ヘッダー rv(関東・東京店)を取り出し、その行のデータ群 row(1200, 1500, 1300, 1600)を保持する。
- 内側ループ: row の値を1つずつスキャンしながら、対応する列ヘッダー cv(2025上期, 2025下期…)とセットにする。
- 内側が4回終了したら、次の外側ループ(関東・横浜店)へ進む。
- 入力データの形状行
ヘッダーr: 4行 × 2列(地域、店舗)
列ヘッダー c: 2行 × 4列(年度、期) $\rightarrow$ .T で 4行 × 2列 に転置
データ本体 v: 4行 × 4列(16個の数値データ) - ループ処理と結合
総繰り返し回数:外側 4回 × 内側 4回 = 16回
生成される各リストの要素数:rv (2) + cv (2) + val (1) = 5列 - 出力データの形状
16行 × 5列 の縦持ちデータフレーム
- インデックス管理エラーの排除
range(len(...)) やインデックス変数(i, j)を使用しないため、範囲外参照(IndexError)や変数指定ミスのリスクがなくなります。 - 高速でシンプルなループ処理
DataFrame のままループを回さず、事前に .values で純粋な NumPy 配列に取り出しておくことで、Python標準の高速なイテレーションが実行されます。 - 構造に対する高い汎用性
行ヘッダーが何列になろうと(例: 地域・店舗・担当者で3列)、列ヘッダーが何行になろうと(例: 年度・四半期・月で3行)、引数の範囲指定(r, c, v)を変えるだけでコード自体は一切変更せずにそのまま適用できる柔軟性を備えています。
重要なのは「計算順序(評価順序)」
「Python in Excel」では、Pythonセルは計算順序に従って評価され、先に定義された関数や変数を後続のPythonセルから参照できます。
ただし、「関数を利用するセル」よりも前に「関数を定義するセル」が評価・計算されていなければ、NameError になります。
つまり、左から右へ1行ずつ進み、行が終わると次の行へ進む順序です。
↓
A2 → B2 → C2 ... (2行目を左から右へ)
OK: A1 で def unpivot... を定義し、B1 や A2 で unpivot(...) を呼び出す。
ブック全体においては、「最も左にあるシートタブ」から順番に Python コードが評価 されます。
(1番目のシート) (2番目のシート) (3番目のシート)
左側のシートで定義された関数や変数は、右側にあるすべてのシートの Python セルから参照可能です。
「専用の定義シート」を最左端に置く運用設計
└── A1セル:def unpivot(r, c, v): ...
│
├── 【売上集計シート】 unpivot(...) で呼び出し
├── 【商品分析シート】 unpivot(...) で呼び出し
└── 【顧客分析シート】 unpivot(...) で呼び出し
- メンテナンス性の向上
コードの改修や不具合修正が必要になった場合も、定義シート(A1 セル)のコードを1箇所修正するだけで、ブック全体の処理が一括更新されます。 - 可読性の向上
呼び出し側のセルには unpivot(...) というシンプルな1行を書くだけで済むため、数式バーが複雑なコードで埋まるのを防げます。
まとめ
- アンピボット関数 unpivot
.values による配列化、.T による転置、zip() とアンパック演算子(*)を組み合わせることで、二次元表をわずか2行で縦持ち化できる。 - 計算順序
ワークシート間では左のシートから右のシートへ、同一シート内では左から右へ1行ずつ進む「行優先順」で評価される。 - 構造化アプローチ
ブックの最左端に「関数定義専用シート」を置き、A1 セル等で共通関数を集約管理するのが実務上扱いやすい。
Excelの計算順序の仕組みを正しく理解し、Pythonコードを「単発のセル処理」から「再利用可能な共通部品」へと進化させることで、より維持管理しやすいブックを構築できます。
同じテーマ「エクセル関数応用」の記事
配列を自在に回転させる数式
掛け算(*)を使わない掛け算|足し算(+)を使わない足し算
2段階の入力規則リスト作成:最新関数対応
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン
「SUMIFSで動くのにXLOOKUPでエラー?」型不一致の関数別挙動
「Python in Excel」で自作関数を登録|アンピボット関数と計算順序
「Python in Excel」数独(ナンプレ)解法プログラムの移植と最適化
Excel表とMarkdownテーブルを相互変換する数式
可変長配列をVSTACKする4つの方法|REDUCE・Thunk・チャンク・再帰分割
Excelの正規表現関数(REGEXTEST・REGEXREPLACE・REGEXEXTRACT)の使い方
「Python in Excel」入門:コードを読むための基礎知識
新着記事NEW ・・・新着記事一覧を見る
「Python in Excel」入門:コードを読むための基礎知識|エクセル関数応用(2026-09-10)
M言語入門:Power Queryのコードを読むための基礎知識|Power Query(M言語)入門(2026-09-09)
Excelの正規表現関数(REGEXTEST・REGEXREPLACE・REGEXEXTRACT)の使い方|エクセル関数応用(2026-09-08)
スピルとVBA(Formula2とスピル範囲の取得)|VBA入門(2026-09-08)
「Withの功罪」:コードを読みやすくする強力な道具と、その落とし穴|VBA技術解説(2026-09-03)
可変長配列をVSTACKする4つの方法|REDUCE・Thunk・チャンク・再帰分割|エクセル関数応用(2026-09-01)
Excel表とMarkdownテーブルを相互変換する数式|エクセル関数応用(2026-08-24)
「Python in Excel」数独(ナンプレ)解法プログラムの移植と最適化|エクセル関数応用(2026-08-14)
「Python in Excel」で自作関数を登録|アンピボット関数と計算順序|エクセル関数応用(2026-08-12)
ListBox・ComboBoxをマウスホイール対応させる|ユーザーフォーム入門(2026-08-09)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.Excelショートカットキー一覧|Excelリファレンス
5.RangeとCellsの使い方|VBA入門
6.FILTER関数(範囲をフィルター処理)|エクセル入門
7.マクロとは?VBAとは?VBAでできること|VBA入門
8.繰り返し処理(For Next)|VBA入門
9.メッセージボックス(MsgBox関数)|VBA入門
10.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.
