{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9fc87869",
   "metadata": {},
   "source": [
    "# 01 데이터 입수 — 취업자·실질부가가치·시나리오 전망\n",
    "\n",
    "**목적.** 취업계수 방식 노동수요 전망에 필요한 입력을 불러오고 검증한다.\n",
    "\n",
    "**2026-10 정비판.** 보고서1은 거시 기준선을 다시 작성하였다. BOKDPM의 장기 정상상태를 현재 여건에 맞추어 고치고(잠재성장률 1.8%, 물가목표 2%, 실질유가 일정),\n",
    "실질금리 외생 투입을 1차 차분으로 바꾸었으며, 외생 경로에 전달되지 않던 시나리오 레버를 연결한 뒤 산업 전망과 정합화를 다시 계산하였다.\n",
    "이 패키지는 그 결과인 5장 정비판 최종 전망으로 주 투입을 바꾸었다. 취업계수의 기준 수준·추세·계수 경로를 정하는 방법과 취업자·부가가치 이력 자료는 바꾸지 않았다.\n",
    "이전 판(2026-10-08 판)의 투입·산출 파일은 `data/published_prev/`에 보존하여 재현 점검과 비교에 쓴다.\n",
    "\n",
    "| 입력 | 내용 | 출처 | 쓰임 |\n",
    "|---|---|---|---|\n",
    "| `data/inputs/emp_section_q.csv` | 산업 대분류(A–U)별 취업자, 분기, 계절조정·원계열, 2013Q1–2025Q4 | 국가데이터처(옛 통계청) 경제활동인구조사(ECOS 901Y027) | 취업계수 |\n",
    "| `data/inputs/va36_hist_q.csv` | 36개 산업 실질부가가치, 계절조정, 분기, 2013Q1–2025Q4 | 한국은행 국민계정(ECOS 200Y104) | 취업계수 |\n",
    "| `data/inputs/va36_reconciled_annual.csv` | 36개 산업 시나리오(S1–S5) 실질부가가치 전망, 연간, 2026–2035 | 보고서1 5장 정비판 최종 전망(5장 재현 패키지 `forecast_annual_36.csv`) | **주 산출물 투입** |\n",
    "| `data/published_prev/va36_reconciled_annual_prev.csv` | 같은 형식, 정비 이전 5장 최종 전망(2026-09-03 판) | 이전 판(2026-10-08 판) 패키지의 주 투입 | 이전 판 재현·비교 |\n",
    "| `data/published_prev/labor_demand_viewer_data_prev.json` | 이전 판 노동수요 산출 파일(포털 뷰어 형식) | 이전 판(2026-10-08 판) 패키지의 주 산출물 | 이전 판 재현 대조 |\n",
    "| `data/inputs/scenario_viewer_39q_data.json` | 36개 산업 시나리오 실질부가가치 전망, 분기, 2026Q1–2035Q4(정합화 이전) | 포털 「산업별 시나리오 전망」 게시 파일(2026-08-04) | 최초 판(v0) 재현 투입 |\n",
    "| `data/section_map_36_19.csv` | 36개 산업 → 대분류 19개 대응표 | 본 연구 설계 | 취업계수 |\n",
    "\n",
    "모든 입력은 공개 통계이거나 본 연구 모형의 공개 산출물이다.\n",
    "\n",
    "**산출물.** `data/interim/emp_section_annual_sa.csv`, `emp_section_annual_nsa.csv`, `va36_hist_annual.csv`, `va36_recon_annual.csv`, `va36_recon_prev_annual.csv`, `va36_scen_annual.csv`\n",
    "\n",
    "기본 실행은 고정 입력만 쓴다. `ONLINE=1`로 실행하면 6절에서 ECOS와 포털의 공개 원천을 다시 받아 고정 입력과 대조한다(ECOS 인증키는 환경변수 `API_KEY_BOK`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "18165894",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:51.717486Z",
     "iopub.status.busy": "2026-10-08T00:07:51.716986Z",
     "iopub.status.idle": "2026-10-08T00:07:52.176553Z",
     "shell.execute_reply": "2026-10-08T00:07:52.176553Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python 3.12.10 · pandas 2.2.3 · numpy 2.4.6 · matplotlib 3.11.0\n",
      "  스위치: ONLINE=0 · FULL=0 · API_KEY_BOK 없음\n",
      "  취업자(분기)            있음  data\\inputs\\emp_section_q.csv\n",
      "  실질VA 이력(분기)        있음  data\\inputs\\va36_hist_q.csv\n",
      "  주 투입: 정비판 VA       있음  data\\inputs\\va36_reconciled_annual.csv\n",
      "  이전 판 투입: VA        있음  data\\published_prev\\va36_reconciled_annual_prev.csv\n",
      "  이전 판 산출 JSON       있음  data\\published_prev\\labor_demand_viewer_data_prev.json\n",
      "  최초 판 투입: 분기 VA     있음  data\\inputs\\scenario_viewer_39q_data.json\n",
      "  최초 판 게시 JSON       있음  data\\published\\labor_demand_viewer_data_v0_pre-reconciliation.json\n",
      "  산업 대응표             있음  data\\section_map_36_19.csv\n"
     ]
    }
   ],
   "source": [
    "import os, json\n",
    "import numpy as np, pandas as pd\n",
    "import config as C\n",
    "import labor_demand as F\n",
    "pd.set_option(\"display.float_format\", lambda v: f\"{v:,.3f}\")\n",
    "C.setup()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec94a9e1",
   "metadata": {},
   "source": [
    "## 1. 고정 입력 확인\n",
    "\n",
    "각 파일의 SHA-256을 `config.INPUT_SHA256`에 기록된 값과 대조한다. 하나라도 다르면 실행을 멈춘다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "11020d19",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:52.177560Z",
     "iopub.status.busy": "2026-10-08T00:07:52.177560Z",
     "iopub.status.idle": "2026-10-08T00:07:52.188664Z",
     "shell.execute_reply": "2026-10-08T00:07:52.188664Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>파일(data/ 기준)</th>\n",
       "      <th>바이트</th>\n",
       "      <th>SHA-256(앞 16자)</th>\n",
       "      <th>기록값 일치</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>inputs/emp_section_q.csv</td>\n",
       "      <td>64507</td>\n",
       "      <td>d631cdcc9aec591e</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>inputs/va36_hist_q.csv</td>\n",
       "      <td>94279</td>\n",
       "      <td>465641eba29c51a8</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>inputs/va36_reconciled_annual.csv</td>\n",
       "      <td>85765</td>\n",
       "      <td>4085f853bbc9ee18</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>inputs/scenario_viewer_39q_data.json</td>\n",
       "      <td>66341</td>\n",
       "      <td>3873c3c575a6c1b1</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>section_map_36_19.csv</td>\n",
       "      <td>2231</td>\n",
       "      <td>b02dbd44aaa03371</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>published_prev/va36_reconciled_annual_prev.csv</td>\n",
       "      <td>85770</td>\n",
       "      <td>779114acd0168928</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>published_prev/labor_demand_viewer_data_prev.json</td>\n",
       "      <td>17222</td>\n",
       "      <td>f3346aee10c08f89</td>\n",
       "      <td>True</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                        파일(data/ 기준)    바이트    SHA-256(앞 16자)  \\\n",
       "0                           inputs/emp_section_q.csv  64507  d631cdcc9aec591e   \n",
       "1                             inputs/va36_hist_q.csv  94279  465641eba29c51a8   \n",
       "2                  inputs/va36_reconciled_annual.csv  85765  4085f853bbc9ee18   \n",
       "3               inputs/scenario_viewer_39q_data.json  66341  3873c3c575a6c1b1   \n",
       "4                              section_map_36_19.csv   2231  b02dbd44aaa03371   \n",
       "5     published_prev/va36_reconciled_annual_prev.csv  85770  779114acd0168928   \n",
       "6  published_prev/labor_demand_viewer_data_prev.json  17222  f3346aee10c08f89   \n",
       "\n",
       "   기록값 일치  \n",
       "0    True  \n",
       "1    True  \n",
       "2    True  \n",
       "3    True  \n",
       "4    True  \n",
       "5    True  \n",
       "6    True  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rows = []\n",
    "for f, want in C.INPUT_SHA256.items():\n",
    "    p = os.path.join(C.DATA, f)\n",
    "    h = F.sha256(p)\n",
    "    rows.append({\"파일(data/ 기준)\": f, \"바이트\": os.path.getsize(p), \"SHA-256(앞 16자)\": h[:16], \"기록값 일치\": h == want})\n",
    "chk = pd.DataFrame(rows)\n",
    "display(chk)\n",
    "assert chk[\"기록값 일치\"].all(), \"고정 입력이 기록된 SHA-256과 다르다\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82da52c5",
   "metadata": {},
   "source": [
    "## 2. 취업자 — 경제활동인구조사 산업 대분류\n",
    "\n",
    "ECOS 901Y027은 한국표준산업분류 대분류 21개(A–U)의 취업자를 2013년부터 제공한다. 계산에는 **분기 계절조정 계열**(구분코드 I28B)을 쓰며,\n",
    "연간 값은 4개 분기의 평균이다. 원계열(I28A)은 02의 명세 비교에만 쓴다.\n",
    "T(가구 내 고용활동)와 U(국제 및 외국기관)는 36개 산업 부가가치 분류에 대응시키지 않으므로 계산에서 제외한다. 두 대분류의 비중은 2013년 0.7%, 2016년 이후 0.3% 수준이다.\n",
    "계절조정은 대분류별로 따로 하므로 대분류 합계와 전체 취업자 계절조정 계열 사이에는 수천 명 이내의 차이가 있다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "dd0be351",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:52.189167Z",
     "iopub.status.busy": "2026-10-08T00:07:52.189167Z",
     "iopub.status.idle": "2026-10-08T00:07:52.205273Z",
     "shell.execute_reply": "2026-10-08T00:07:52.205273Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "계절조정: 2013Q1–2025Q4 · 52개 분기 · 대분류 21개 + 전체\n",
      "원계열: 2013Q1–2025Q4 · 52개 분기 · 대분류 21개 + 전체\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>전체(천명)</th>\n",
       "      <th>A–S 합계(천명)</th>\n",
       "      <th>T+U(천명)</th>\n",
       "      <th>T+U 비중(%)</th>\n",
       "      <th>A–U 합계 − 전체(천명)</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>연도</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013</th>\n",
       "      <td>25,298.250</td>\n",
       "      <td>25,113.500</td>\n",
       "      <td>180.250</td>\n",
       "      <td>0.712</td>\n",
       "      <td>-4.500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016</th>\n",
       "      <td>26,408.750</td>\n",
       "      <td>26,321.500</td>\n",
       "      <td>86.250</td>\n",
       "      <td>0.327</td>\n",
       "      <td>-1.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019</th>\n",
       "      <td>27,123.750</td>\n",
       "      <td>27,039.750</td>\n",
       "      <td>86.500</td>\n",
       "      <td>0.319</td>\n",
       "      <td>2.500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2022</th>\n",
       "      <td>28,091.250</td>\n",
       "      <td>27,993.000</td>\n",
       "      <td>96.250</td>\n",
       "      <td>0.343</td>\n",
       "      <td>-2.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2023</th>\n",
       "      <td>28,418.750</td>\n",
       "      <td>28,321.250</td>\n",
       "      <td>94.500</td>\n",
       "      <td>0.333</td>\n",
       "      <td>-3.000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2024</th>\n",
       "      <td>28,577.250</td>\n",
       "      <td>28,482.250</td>\n",
       "      <td>94.500</td>\n",
       "      <td>0.331</td>\n",
       "      <td>-0.500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2025</th>\n",
       "      <td>28,769.000</td>\n",
       "      <td>28,681.500</td>\n",
       "      <td>91.000</td>\n",
       "      <td>0.316</td>\n",
       "      <td>3.500</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         전체(천명)  A–S 합계(천명)  T+U(천명)  T+U 비중(%)  A–U 합계 − 전체(천명)\n",
       "연도                                                              \n",
       "2013 25,298.250  25,113.500  180.250      0.712           -4.500\n",
       "2016 26,408.750  26,321.500   86.250      0.327           -1.000\n",
       "2019 27,123.750  27,039.750   86.500      0.319            2.500\n",
       "2022 28,091.250  27,993.000   96.250      0.343           -2.000\n",
       "2023 28,418.750  28,321.250   94.500      0.333           -3.000\n",
       "2024 28,577.250  28,482.250   94.500      0.331           -0.500\n",
       "2025 28,769.000  28,681.500   91.000      0.316            3.500"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "emp_q = {adj: F.read_employment(C.EMP_Q, adj) for adj in [\"계절조정\", \"원계열\"]}\n",
    "for adj, q in emp_q.items():\n",
    "    print(f\"{adj}: {q.index.min()}–{q.index.max()} · {q.shape[0]}개 분기 · 대분류 {q.shape[1] - 1}개 + 전체\")\n",
    "emp_a = {adj: F.annual_employment(q) for adj, q in emp_q.items()}\n",
    "a = emp_a[\"계절조정\"]\n",
    "tu = a[[\"T\", \"U\"]].sum(axis=1)\n",
    "pd.DataFrame({\"전체(천명)\": a[\"전체\"], \"A–S 합계(천명)\": a[F.SECTIONS].sum(axis=1),\n",
    "              \"T+U(천명)\": tu, \"T+U 비중(%)\": 100 * tu / a[\"전체\"],\n",
    "              \"A–U 합계 − 전체(천명)\": a[F.SECTIONS + [\"T\", \"U\"]].sum(axis=1) - a[\"전체\"]}).loc[[2013, 2016, 2019, 2022, 2023, 2024, 2025]]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f21612e5",
   "metadata": {},
   "source": [
    "## 3. 실질부가가치 이력 — 36개 산업\n",
    "\n",
    "한국은행 경제활동별 GDP(계절조정, 실질, 분기) 36개 말단 산업이다. 단위는 십억 원(2020년 연쇄가격)이고, 연간 값은 4개 분기의 합계이다.\n",
    "대응표는 각 산업을 하나의 대분류에 배정한다. 제조업(C)은 13개, 건설업(F)은 4개, 전기·가스(D)와 정보통신(J)은 각 2개 산업을 묶는다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7b7d2b83",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:52.206278Z",
     "iopub.status.busy": "2026-10-08T00:07:52.206278Z",
     "iopub.status.idle": "2026-10-08T00:07:52.215599Z",
     "shell.execute_reply": "2026-10-08T00:07:52.215599Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "실질부가가치: 2013Q1–2025Q4 · 52개 분기 · 산업 36개\n",
      "36개 산업 합계: 2013년 1,599.2조 원 → 2025년 2,178.5조 원\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>36개 산업</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>대분류</th>\n",
       "      <th>대분류명</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>A</th>\n",
       "      <th>농업, 임업 및 어업</th>\n",
       "      <td>농림어업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>B</th>\n",
       "      <th>광업</th>\n",
       "      <td>광업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>C</th>\n",
       "      <th>제조업</th>\n",
       "      <td>음식료품 제조업 · 섬유 및 가죽제품 제조업 · 목재, 종이, 인쇄 및 복제업 · ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>D</th>\n",
       "      <th>전기, 가스, 증기 및 공기조절 공급업</th>\n",
       "      <td>전기업 · 가스, 증기 및 공기조절 공급업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>E</th>\n",
       "      <th>수도, 하수 및 폐기물 처리, 원료 재생업</th>\n",
       "      <td>수도, 하수 및 폐기물 처리, 원료 재생업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F</th>\n",
       "      <th>건설업</th>\n",
       "      <td>주거용 건물 건설업 · 비주거용 건물 건설업 · 토목건설업 · 건축보수업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>G</th>\n",
       "      <th>도매 및 소매업</th>\n",
       "      <td>도소매업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>H</th>\n",
       "      <th>운수 및 창고업</th>\n",
       "      <td>운수업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>I</th>\n",
       "      <th>숙박 및 음식점업</th>\n",
       "      <td>숙박 및 음식점업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>J</th>\n",
       "      <th>정보통신업</th>\n",
       "      <td>통신업 · 출판, 방송, 영상, 정보서비스</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>K</th>\n",
       "      <th>금융 및 보험업</th>\n",
       "      <td>금융 및 보험업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>L</th>\n",
       "      <th>부동산업</th>\n",
       "      <td>부동산업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>M</th>\n",
       "      <th>전문, 과학 및 기술 서비스업</th>\n",
       "      <td>전문, 과학 및 기술관련 서비스업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>N</th>\n",
       "      <th>사업시설 관리, 사업 지원 및 임대 서비스업</th>\n",
       "      <td>사업지원 서비스업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>O</th>\n",
       "      <th>공공행정, 국방 및 사회보장 행정</th>\n",
       "      <td>공공행정, 국방 및 사회보장</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>P</th>\n",
       "      <th>교육 서비스업</th>\n",
       "      <td>교육서비스업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Q</th>\n",
       "      <th>보건업 및 사회복지 서비스업</th>\n",
       "      <td>의료, 보건업 및 사회복지서비스업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>R</th>\n",
       "      <th>예술, 스포츠 및 여가관련 서비스업</th>\n",
       "      <td>예술, 스포츠 및 여가관련 서비스업</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S</th>\n",
       "      <th>협회 및 단체, 수리 및 기타 개인 서비스업</th>\n",
       "      <td>기타 서비스업</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                                         36개 산업\n",
       "대분류 대분류명                                                                       \n",
       "A   농업, 임업 및 어업                                                            농림어업\n",
       "B   광업                                                                       광업\n",
       "C   제조업                       음식료품 제조업 · 섬유 및 가죽제품 제조업 · 목재, 종이, 인쇄 및 복제업 · ...\n",
       "D   전기, 가스, 증기 및 공기조절 공급업                               전기업 · 가스, 증기 및 공기조절 공급업\n",
       "E   수도, 하수 및 폐기물 처리, 원료 재생업                             수도, 하수 및 폐기물 처리, 원료 재생업\n",
       "F   건설업                                주거용 건물 건설업 · 비주거용 건물 건설업 · 토목건설업 · 건축보수업\n",
       "G   도매 및 소매업                                                               도소매업\n",
       "H   운수 및 창고업                                                                운수업\n",
       "I   숙박 및 음식점업                                                         숙박 및 음식점업\n",
       "J   정보통신업                                               통신업 · 출판, 방송, 영상, 정보서비스\n",
       "K   금융 및 보험업                                                           금융 및 보험업\n",
       "L   부동산업                                                                   부동산업\n",
       "M   전문, 과학 및 기술 서비스업                                         전문, 과학 및 기술관련 서비스업\n",
       "N   사업시설 관리, 사업 지원 및 임대 서비스업                                          사업지원 서비스업\n",
       "O   공공행정, 국방 및 사회보장 행정                                          공공행정, 국방 및 사회보장\n",
       "P   교육 서비스업                                                              교육서비스업\n",
       "Q   보건업 및 사회복지 서비스업                                          의료, 보건업 및 사회복지서비스업\n",
       "R   예술, 스포츠 및 여가관련 서비스업                                     예술, 스포츠 및 여가관련 서비스업\n",
       "S   협회 및 단체, 수리 및 기타 개인 서비스업                                            기타 서비스업"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "va_q = F.read_va_hist(C.VA_HIST_Q)\n",
    "smap = pd.read_csv(C.SECTION_MAP, dtype={\"산업코드\": str})\n",
    "sec_of = dict(zip(smap[\"산업명\"], smap[\"대분류\"]))\n",
    "assert set(va_q.columns) == set(sec_of), \"대응표와 부가가치 자료의 산업 이름이 다르다\"\n",
    "assert sorted(set(sec_of.values())) == F.SECTIONS, \"대응표의 대분류가 A–S 19개가 아니다\"\n",
    "va_a = F.annual_va(va_q)\n",
    "print(f\"실질부가가치: {va_q.index.min()}–{va_q.index.max()} · {va_q.shape[0]}개 분기 · 산업 {va_q.shape[1]}개\")\n",
    "print(f\"36개 산업 합계: 2013년 {va_a.loc[2013].sum() / 1e3:,.1f}조 원 → 2025년 {va_a.loc[2025].sum() / 1e3:,.1f}조 원\")\n",
    "smap.groupby([\"대분류\", \"대분류명\"])[\"산업명\"].apply(lambda s: \" · \".join(s)).to_frame(\"36개 산업\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9df3e05d",
   "metadata": {},
   "source": [
    "## 4. 시나리오 실질부가가치 전망 — 주 투입, 이전 판 투입, 최초 판 투입\n",
    "\n",
    "**주 투입(정비판)**은 보고서1 5장의 2026-10 정비판 최종 전망이다. 산업 VARX 합산 경로를 총량 전망에 맞추어 비례배분(산업 구성비 유지)하고 기존 전망과 결합한 연간 값이다.\n",
    "\n",
    "**이전 판 투입**은 정비 이전의 5장 최종 전망(2026-09-03 판)이며, 이전 판(2026-10-08 판) 노동수요가 투입한 값이다. 파일 형식과 산업·연도·시나리오 구성은 주 투입과 같다.\n",
    "\n",
    "**최초 판 투입**은 2026-08-04 포털 「산업별 시나리오 전망」에 게시된 정합화 이전 분기 전망(연간 값은 4개 분기 합계)이다. 같은 날 게시된 노동수요 자료(최초 판, v0)가 이 값을 투입했으며,\n",
    "이 패키지는 그 파일을 바이트 단위까지 재현하는 데에만 이 자료를 쓴다.\n",
    "\n",
    "표의 연평균 증가율은 2025년 실적(36개 산업 합계)에서 2035년 전망까지의 값이다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "44049f64",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:52.216602Z",
     "iopub.status.busy": "2026-10-08T00:07:52.216602Z",
     "iopub.status.idle": "2026-10-08T00:07:52.236158Z",
     "shell.execute_reply": "2026-10-08T00:07:52.236158Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2025년 실적(36개 산업 합계): 2,178.5조 원\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>정비판 2026(조원)</th>\n",
       "      <th>정비판 2035(조원)</th>\n",
       "      <th>정비판 연평균(%)</th>\n",
       "      <th>이전 판 2035(조원)</th>\n",
       "      <th>이전 판 연평균(%)</th>\n",
       "      <th>정비판 − 이전 판 2035(조원)</th>\n",
       "      <th>최초 판 2035(조원)</th>\n",
       "      <th>최초 판 연평균(%)</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>S1</th>\n",
       "      <td>2,221.070</td>\n",
       "      <td>2,609.030</td>\n",
       "      <td>1.820</td>\n",
       "      <td>2,688.520</td>\n",
       "      <td>2.130</td>\n",
       "      <td>-79.490</td>\n",
       "      <td>3,285.330</td>\n",
       "      <td>4.190</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S2</th>\n",
       "      <td>2,198.320</td>\n",
       "      <td>2,605.860</td>\n",
       "      <td>1.810</td>\n",
       "      <td>2,650.290</td>\n",
       "      <td>1.980</td>\n",
       "      <td>-44.430</td>\n",
       "      <td>3,218.600</td>\n",
       "      <td>3.980</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S3</th>\n",
       "      <td>2,233.440</td>\n",
       "      <td>2,612.180</td>\n",
       "      <td>1.830</td>\n",
       "      <td>2,708.630</td>\n",
       "      <td>2.200</td>\n",
       "      <td>-96.450</td>\n",
       "      <td>3,312.210</td>\n",
       "      <td>4.280</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S4</th>\n",
       "      <td>2,233.580</td>\n",
       "      <td>2,607.700</td>\n",
       "      <td>1.810</td>\n",
       "      <td>2,740.690</td>\n",
       "      <td>2.320</td>\n",
       "      <td>-132.990</td>\n",
       "      <td>3,307.090</td>\n",
       "      <td>4.260</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>S5</th>\n",
       "      <td>2,203.210</td>\n",
       "      <td>2,610.230</td>\n",
       "      <td>1.820</td>\n",
       "      <td>2,664.240</td>\n",
       "      <td>2.030</td>\n",
       "      <td>-54.010</td>\n",
       "      <td>3,259.990</td>\n",
       "      <td>4.110</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    정비판 2026(조원)  정비판 2035(조원)  정비판 연평균(%)  이전 판 2035(조원)  이전 판 연평균(%)  \\\n",
       "S1     2,221.070     2,609.030       1.820      2,688.520        2.130   \n",
       "S2     2,198.320     2,605.860       1.810      2,650.290        1.980   \n",
       "S3     2,233.440     2,612.180       1.830      2,708.630        2.200   \n",
       "S4     2,233.580     2,607.700       1.810      2,740.690        2.320   \n",
       "S5     2,203.210     2,610.230       1.820      2,664.240        2.030   \n",
       "\n",
       "    정비판 − 이전 판 2035(조원)  최초 판 2035(조원)  최초 판 연평균(%)  \n",
       "S1              -79.490      3,285.330        4.190  \n",
       "S2              -44.430      3,218.600        3.980  \n",
       "S3              -96.450      3,312.210        4.280  \n",
       "S4             -132.990      3,307.090        4.260  \n",
       "S5              -54.010      3,259.990        4.110  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recon = F.read_reconciled(C.RECON_CSV)\n",
    "recon_prev = F.read_reconciled(C.PREV_RECON_CSV)\n",
    "scen_a = F.scenario_annual(F.read_scenario_json(C.SCEN_JSON))\n",
    "for s in C.SCENARIOS:\n",
    "    for d in (recon, recon_prev, scen_a):\n",
    "        assert set(d[s].columns) == set(sec_of) and list(d[s].index) == C.FORECAST_YEARS\n",
    "b25 = va_a.loc[2025].sum()\n",
    "print(f\"2025년 실적(36개 산업 합계): {b25 / 1e3:,.1f}조 원\")\n",
    "pd.DataFrame({s: {\"정비판 2026(조원)\": recon[s].loc[2026].sum() / 1e3,\n",
    "                  \"정비판 2035(조원)\": recon[s].loc[2035].sum() / 1e3,\n",
    "                  \"정비판 연평균(%)\": F.cagr(b25, recon[s].loc[2035].sum(), 10),\n",
    "                  \"이전 판 2035(조원)\": recon_prev[s].loc[2035].sum() / 1e3,\n",
    "                  \"이전 판 연평균(%)\": F.cagr(b25, recon_prev[s].loc[2035].sum(), 10),\n",
    "                  \"정비판 − 이전 판 2035(조원)\": (recon[s].loc[2035].sum() - recon_prev[s].loc[2035].sum()) / 1e3,\n",
    "                  \"최초 판 2035(조원)\": scen_a[s].loc[2035].sum() / 1e3,\n",
    "                  \"최초 판 연평균(%)\": F.cagr(b25, scen_a[s].loc[2035].sum(), 10)} for s in C.SCENARIOS}).T.round(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "981cfb98",
   "metadata": {},
   "source": [
    "## 5. 주 투입의 원본 대조 — 5장 재현 패키지\n",
    "\n",
    "주 투입은 5장 재현 패키지의 동결 산출물 `s5-results/data/published/forecast_annual_36.csv`(실적 2000–2025년, S1–S5 2026–2035년)에서\n",
    "S1–S5·2026–2035년 행만 문자 그대로 옮긴 파일이다. 이 패키지가 5장 패키지와 같은 폴더 구조(`repro/report-gva/`)에 있으면 다음을 확인한다.\n",
    "\n",
    "- 원본의 SHA-256이 `config.SOURCE_SHA256`과 같은지\n",
    "- 원본에서 추린 행이 고정 입력과 바이트 단위로 같은지\n",
    "- 원본의 2025년 실적 행이 `va36_hist_q.csv`의 2025년 4개 분기 합계와 같은지\n",
    "\n",
    "배포 묶음처럼 원본이 없으면 이 절을 건너뛴다. 결과는 보고만 하고 실행을 멈추지 않는다. 고정 입력 자체의 동일성은 1절의 SHA-256 대조가 보장한다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "925f351f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:52.237162Z",
     "iopub.status.busy": "2026-10-08T00:07:52.237162Z",
     "iopub.status.idle": "2026-10-08T00:07:52.244993Z",
     "shell.execute_reply": "2026-10-08T00:07:52.244993Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>항목</th>\n",
       "      <th>결과</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>원본 SHA-256</td>\n",
       "      <td>ae396b0eead6d696… · 기록값(정비판)과 일치</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>원본의 S1–S5·2026–2035 행 = 고정 입력</td>\n",
       "      <td>바이트 단위 일치</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>원본 2025년 실적 = va36_hist_q 2025년 합계</td>\n",
       "      <td>36개 산업 · 최대 차이 7.28e-12십억 원</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                   항목                                결과\n",
       "0                          원본 SHA-256  ae396b0eead6d696… · 기록값(정비판)과 일치\n",
       "1       원본의 S1–S5·2026–2035 행 = 고정 입력                         바이트 단위 일치\n",
       "2  원본 2025년 실적 = va36_hist_q 2025년 합계       36개 산업 · 최대 차이 7.28e-12십억 원"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "if not os.path.exists(C.S5_SOURCE):\n",
    "    print(f\"5장 원본이 없어 건너뛴다({os.path.relpath(C.S5_SOURCE, C.HERE)}). 기록된 원본 SHA-256: {C.SOURCE_SHA256[:16]}…\")\n",
    "else:\n",
    "    raw = open(C.S5_SOURCE, \"rb\").read()\n",
    "    hs = F.sha256_bytes(raw)\n",
    "    same = F.reconciled_subset_bytes(raw) == open(C.RECON_CSV, \"rb\").read()\n",
    "    src = pd.read_csv(C.S5_SOURCE)\n",
    "    a25 = src[(src[\"시나리오\"] == \"실적\") & (src[\"연도\"] == 2025)].set_index(\"산업\")[\"실질VA_십억원\"]\n",
    "    d25 = (a25 - va_a.loc[2025, a25.index]).abs().max()\n",
    "    tag = (\"기록값(정비판)과 일치\" if hs == C.SOURCE_SHA256 else\n",
    "           \"이전 판 원본(2026-09-03 판)과 일치\" if hs == C.PREV_SOURCE_SHA256 else \"기록값과 다름 — 5장 산출물이 바뀌었으므로 주 투입을 다시 만들어야 한다\")\n",
    "    display(pd.DataFrame([\n",
    "        {\"항목\": \"원본 SHA-256\", \"결과\": f\"{hs[:16]}… · {tag}\"},\n",
    "        {\"항목\": \"원본의 S1–S5·2026–2035 행 = 고정 입력\", \"결과\": \"바이트 단위 일치\" if same else \"다름\"},\n",
    "        {\"항목\": \"원본 2025년 실적 = va36_hist_q 2025년 합계\", \"결과\": f\"{len(a25)}개 산업 · 최대 차이 {d25:.2e}십억 원\"}]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a8bcf03",
   "metadata": {},
   "source": [
    "## 6. 공개 원천과 대조(ONLINE=1)\n",
    "\n",
    "- 통합 번들(`gva-scenario-bundle.zip`)을 내려받아 주 투입의 원본(`industry/output/forecast_annual_36.csv`)이 고정 입력과 같은지 확인한다.\n",
    "  번들이 아직 이전 판 원본(2026-09-03 판)을 담고 있으면 그 사실을 보고한다.\n",
    "- 포털의 최초 판 투입 자료(`scenario_viewer_39q_data.json`)의 SHA-256을 확인한다.\n",
    "- 포털의 노동수요 JSON(현행 주소와 최초 판 주소)을 `data/interim/portal/`에 내려받는다. 산출물과의 비교는 `03_결과.ipynb`에서 한다.\n",
    "- ECOS에서 취업자(901Y027)와 실질부가가치(200Y104)를 다시 받아 비교한다. 계절조정 계열은 새 자료가 들어올 때마다 과거 값이 다시 추정되므로 수집 시점에 따라 작은 차이가 생길 수 있다.\n",
    "\n",
    "차이는 보고만 하고 실행을 멈추지 않는다. 취업자·부가가치 고정 입력은 2026-10-08에 수집했다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "033e5ecb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:52.245996Z",
     "iopub.status.busy": "2026-10-08T00:07:52.245996Z",
     "iopub.status.idle": "2026-10-08T00:07:52.250843Z",
     "shell.execute_reply": "2026-10-08T00:07:52.250843Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ONLINE=0: 고정 입력을 그대로 쓴다. 공개 원천과 다시 대조하려면 ONLINE=1로 실행한다.\n"
     ]
    }
   ],
   "source": [
    "if not C.ONLINE:\n",
    "    print(\"ONLINE=0: 고정 입력을 그대로 쓴다. 공개 원천과 다시 대조하려면 ONLINE=1로 실행한다.\")\n",
    "else:\n",
    "    os.makedirs(C.PORTAL_DL, exist_ok=True)\n",
    "    res = []\n",
    "    zp = os.path.join(C.PORTAL_DL, \"gva-scenario-bundle.zip\")\n",
    "    h, st = F.try_download(C.URL_BUNDLE, zp)\n",
    "    if h is None:\n",
    "        res.append({\"항목\": \"통합 번들\", \"결과\": st})\n",
    "    else:\n",
    "        raw = F.bundle_member(zp, C.BUNDLE_MEMBER)\n",
    "        hm = F.sha256_bytes(raw)\n",
    "        sub = F.reconciled_subset(raw)\n",
    "        fix = pd.read_csv(C.RECON_CSV)\n",
    "        m = fix.merge(sub, on=[\"시나리오\", \"연도\", \"산업\"], how=\"outer\", suffixes=(\"_고정\", \"_번들\"))\n",
    "        dmax = (m[\"실질VA_십억원_고정\"] - m[\"실질VA_십억원_번들\"]).abs().max()\n",
    "        tag = (\"정비판 원본과 일치\" if hm == C.SOURCE_SHA256 else\n",
    "               \"이전 판 원본(2026-09-03 판)과 일치 — 포털 번들이 아직 갱신되지 않았다\" if hm == C.PREV_SOURCE_SHA256 else\n",
    "               \"기록값과 다름(\" + hm[:12] + \"…)\")\n",
    "        res.append({\"항목\": f\"번들 {C.BUNDLE_MEMBER}\",\n",
    "                    \"결과\": f\"SHA-256 {tag} · S1–S5·2026–2035 {len(sub)}행, 고정 입력과 최대 차이 {dmax:.3f}십억 원\"})\n",
    "    h, st = F.try_download(C.URL_SCEN, os.path.join(C.PORTAL_DL, \"scenario_viewer_39q_data.json\"))\n",
    "    res.append({\"항목\": \"포털 scenario_viewer_39q_data.json\",\n",
    "                \"결과\": st if h is None else (\"SHA-256 일치\" if h == C.INPUT_SHA256[\"inputs/scenario_viewer_39q_data.json\"] else f\"SHA-256 다름({h[:12]}…)\")})\n",
    "    for name, url in [(\"labor_demand_viewer_data.json\", C.URL_MAIN),\n",
    "                      (\"labor_demand_viewer_data_v0_pre-reconciliation.json\", C.URL_V0)]:\n",
    "        h, st = F.try_download(url, os.path.join(C.PORTAL_DL, name))\n",
    "        res.append({\"항목\": f\"포털 {name}\", \"결과\": st if h is None else f\"내려받음(SHA-256 {h[:12]}…), 03에서 비교\"})\n",
    "    key = os.environ.get(C.KEY_ENV)\n",
    "    if not key:\n",
    "        res.append({\"항목\": \"ECOS\", \"결과\": f\"환경변수 {C.KEY_ENV}가 없어 건너뛴다\"})\n",
    "    else:\n",
    "        e_new = F.fetch_employment(key, \"2013Q1\", \"2025Q4\")\n",
    "        e_old = pd.read_csv(C.EMP_Q, dtype={\"분기\": str})\n",
    "        m = e_old.merge(e_new, on=[\"분기\", \"대분류\", \"구분\"], how=\"outer\", suffixes=(\"_고정\", \"_재수집\"))\n",
    "        for adj in [\"계절조정\", \"원계열\"]:\n",
    "            d = m[m[\"구분\"] == adj]\n",
    "            diff = (d[\"취업자_천명_고정\"] - d[\"취업자_천명_재수집\"]).abs()\n",
    "            res.append({\"항목\": f\"ECOS 901Y027 취업자({adj})\",\n",
    "                        \"결과\": f\"{len(d)}개 값 · 최대 차이 {diff.max():.1f}천 명 · 결측 {int(diff.isna().sum())}개\"})\n",
    "        v_new = F.fetch_va36(key, smap[\"산업코드\"].tolist())\n",
    "        v_old = pd.read_csv(C.VA_HIST_Q, dtype={\"분기\": str, \"산업코드\": str})\n",
    "        mv = v_old.merge(v_new, on=[\"분기\", \"산업코드\"], how=\"outer\", suffixes=(\"_고정\", \"_재수집\"))\n",
    "        dv = (mv[\"실질VA_십억원_고정\"] - mv[\"실질VA_십억원_재수집\"]).abs()\n",
    "        res.append({\"항목\": \"ECOS 200Y104 실질부가가치\",\n",
    "                    \"결과\": f\"{len(mv)}개 값 · 최대 차이 {dv.max():.1f}십억 원 · 결측 {int(dv.isna().sum())}개\"})\n",
    "    display(pd.DataFrame(res))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04a7962f",
   "metadata": {},
   "source": [
    "## 7. 산출물\n",
    "\n",
    "다음 노트북(`02_분석.ipynb`)은 아래 중간 산출물과 대응표를 읽는다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ec569529",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-10-08T00:07:52.251847Z",
     "iopub.status.busy": "2026-10-08T00:07:52.251847Z",
     "iopub.status.idle": "2026-10-08T00:07:52.272323Z",
     "shell.execute_reply": "2026-10-08T00:07:52.272323Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "emp_section_annual_nsa.csv      2,120 bytes\n",
      "emp_section_annual_sa.csv       2,130 bytes\n",
      "va36_hist_annual.csv            5,184 bytes\n",
      "va36_recon_annual.csv          85,765 bytes\n",
      "va36_recon_prev_annual.csv     85,770 bytes\n",
      "va36_scen_annual.csv           86,440 bytes\n"
     ]
    }
   ],
   "source": [
    "emp_a[\"계절조정\"].to_csv(os.path.join(C.INTERIM, \"emp_section_annual_sa.csv\"), encoding=\"utf-8-sig\")\n",
    "emp_a[\"원계열\"].to_csv(os.path.join(C.INTERIM, \"emp_section_annual_nsa.csv\"), encoding=\"utf-8-sig\")\n",
    "va_a.to_csv(os.path.join(C.INTERIM, \"va36_hist_annual.csv\"), encoding=\"utf-8-sig\")\n",
    "def long(d):\n",
    "    return pd.concat([v.stack().rename(\"실질VA_십억원\").reset_index().set_axis([\"연도\", \"산업\", \"실질VA_십억원\"], axis=1).assign(시나리오=s)\n",
    "                      for s, v in d.items()])[[\"시나리오\", \"연도\", \"산업\", \"실질VA_십억원\"]]\n",
    "long(recon).to_csv(os.path.join(C.INTERIM, \"va36_recon_annual.csv\"), index=False, encoding=\"utf-8-sig\")\n",
    "long(recon_prev).to_csv(os.path.join(C.INTERIM, \"va36_recon_prev_annual.csv\"), index=False, encoding=\"utf-8-sig\")\n",
    "long(scen_a).to_csv(os.path.join(C.INTERIM, \"va36_scen_annual.csv\"), index=False, encoding=\"utf-8-sig\")\n",
    "for f in sorted(os.listdir(C.INTERIM)):\n",
    "    p = os.path.join(C.INTERIM, f)\n",
    "    if os.path.isfile(p):\n",
    "        print(f\"{f:<28} {os.path.getsize(p):>8,d} bytes\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
