<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Japan Open Data Lab</title>
    <description>The latest articles on DEV Community by Japan Open Data Lab (@japanopendatalab).</description>
    <link>https://dev.to/japanopendatalab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4185683%2F8a0a9228-0dc7-49e3-bb7e-6e81e7f3b454.jpg</url>
      <title>DEV Community: Japan Open Data Lab</title>
      <link>https://dev.to/japanopendatalab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/japanopendatalab"/>
    <language>en</language>
    <item>
      <title>Thought Experiment: If 100GB of structured/3D data could be losslessly compressed to 1GB, what would you build?</title>
      <dc:creator>Japan Open Data Lab</dc:creator>
      <pubDate>Thu, 22 Oct 2026 00:30:00 +0000</pubDate>
      <link>https://dev.to/japanopendatalab/thought-experiment-if-100gb-of-structured3d-data-could-be-losslessly-compressed-to-1gb-what-1bfc</link>
      <guid>https://dev.to/japanopendatalab/thought-experiment-if-100gb-of-structured3d-data-could-be-losslessly-compressed-to-1gb-what-1bfc</guid>
      <description>&lt;p&gt;This post is a pure thought experiment exploring what kind of system designs and products would become possible if data size constraints suddenly shrank to 1/100th of what they are today.&lt;/p&gt;

&lt;p&gt;​The Problem: Data That Cannot Lose a Single Bit is Getting Too Heavy&lt;br&gt;
​Anyone building or maintaining systems today feels the growing pain of data bloat.&lt;/p&gt;

&lt;p&gt;​With images and videos, we can rely on lossy compression to trick the human eye. But when it comes to data where neither a single bit of precision nor the exact order of rows can be altered, we don't have that luxury:&lt;br&gt;
​Nationwide 3D city models and point cloud data used in smart cities and surveying&lt;br&gt;
​Spatial sensor logs recorded by autonomous vehicles and robotics&lt;br&gt;
​Millisecond-level financial tick data and massive transaction histories&lt;br&gt;
​Databases and log files bloated to hundreds of millions or billions of records&lt;br&gt;
​Even with existing compression algorithms, &lt;br&gt;
these datasets easily reach hundreds of gigabytes or terabytes. They drive up cloud storage costs (like S3), query scan fees (like BigQuery), and above all, create a hard physical wall: they are simply too heavy to fit into local machines or standard server RAM.&lt;/p&gt;

&lt;p&gt;​The Hypothesis: A World Where 100GB+ Data Becomes 1GB (100% Lossless)&lt;br&gt;
​So, I started playing around with a quick thought experiment:&lt;br&gt;
​What if a technology existed that could shrink 100GB+ of massive numerical, structured, or 3D spatial data down to under 1GB (a 100x reduction)—while keeping 100% of the original row order and precision (completely lossless, with identical SHA-256 hashes upon decompression)?&lt;/p&gt;

&lt;p&gt;​Furthermore, what if it had the characteristic where the larger the original dataset, the higher the compression ratio (for instance, shrinking an 800GB dataset down to just a few gigabytes)? How would our infrastructure design philosophy change?&lt;/p&gt;

&lt;p&gt;​1. Fitting an 800GB Nationwide 3D Map into Standard Laptop RAM&lt;br&gt;
​Right now, high-precision 3D geospatial data and point clouds are so massive that you need dedicated high-end workstations or large-scale GIS servers just to touch them.&lt;br&gt;
If an 800GB dataset shrank to a few gigabytes, you could load an entire country's 3D map directly into the RAM of a standard laptop or even a web browser environment—with zero loading times. The barriers to building disaster simulations, digital twins, and massive open-world games would collapse overnight.&lt;/p&gt;

&lt;p&gt;​2. Keeping 100% of Raw Autonomous Driving and IoT Logs without Downsampling&lt;br&gt;
​When sending data from edge devices to the cloud, we currently have to compromise due to bandwidth and storage limits—recording only anomalies or downsampling to averages.&lt;br&gt;
If data volume dropped to 1/100th, we could stream and permanently store every single raw driving log and sensor history without throwing anything away.&lt;/p&gt;

&lt;p&gt;​3. Freedom from DB Archiving and Painful Cleanup Batch Jobs&lt;br&gt;
​We could finally ditch tearful data lifecycle rules like "Keep only the last 3 months in hot storage and delete or banish the rest to cold storage." Years or even decades of raw historical data could remain online and instantly queryable at all times.&lt;br&gt;
​What Data Would You Throw Into It, and What Would You Build?&lt;/p&gt;

&lt;p&gt;​When data shrinks to this extreme, it goes way beyond saving on cloud bills—it unlocks features and services we previously gave up on because the data was simply too heavy.&lt;br&gt;
​If a "black box" that losslessly shrinks massive structured and 3D data by 100x suddenly landed on your desk today, what dataset would you feed it first, and what kind of system would you build?&lt;br&gt;
​Whether it's "This would solve a massive bottleneck in my industry" or "It would let me build this crazy architecture," I'd love to hear your ideas in the comments!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>architecture</category>
      <category>dataengineering</category>
      <category>database</category>
    </item>
    <item>
      <title>Building an Automated Python ETL Pipeline for Japan's 1,741 Municipalities Open Data (SSDSE-A)</title>
      <dc:creator>Japan Open Data Lab</dc:creator>
      <pubDate>Sun, 18 Oct 2026 11:43:12 +0000</pubDate>
      <link>https://dev.to/japanopendatalab/building-an-automated-python-etl-pipeline-for-japans-1741-municipalities-open-data-ssdse-a-5930</link>
      <guid>https://dev.to/japanopendatalab/building-an-automated-python-etl-pipeline-for-japans-1741-municipalities-open-data-ssdse-a-5930</guid>
      <description>&lt;p&gt;Japan's Statistics Bureau (Ministry of Internal Affairs and Communications) and the National Statistics Center (NSTAC) publish an extraordinary open dataset called &lt;strong&gt;SSDSE (System of Social and Demographic Statistics)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Specifically, &lt;strong&gt;SSDSE-A&lt;/strong&gt; covers all &lt;strong&gt;1,741 municipalities&lt;/strong&gt; across Japan, aggregating 128 comprehensive public indicators including demographics, households, economic activities, labor forces, municipal finance, healthcare facilities, and education.&lt;/p&gt;

&lt;p&gt;However, if you simply pass this dataset into &lt;code&gt;pd.read_csv()&lt;/code&gt;, you immediately encounter classic government data traps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A multi-level 3-row header&lt;/strong&gt; that breaks schema inference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legacy Shift-JIS (CP932) encoding&lt;/strong&gt; that throws &lt;code&gt;UnicodeDecodeError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefixed municipality codes (&lt;code&gt;R01100&lt;/code&gt;) and dropping leading zeros&lt;/strong&gt;, destroying relational keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing derived analytical KPIs&lt;/strong&gt; like habitable population density and aging ratios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I'll walk through building a clean, automated Python pipeline to ingest, normalize, enrich, and export Japan's census open data into flat, modern formats (Parquet, BOM-UTF8 CSV, SQLite).&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Anatomy of the Raw CSV (And Its 4 Traps)
&lt;/h2&gt;

&lt;p&gt;Here is a glimpse of the raw &lt;code&gt;SSDSE-A-2026.csv&lt;/code&gt; published by NSTAC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;地域コード,都道府県,市区町村,A1101,A110101,A110102,...
,,,2020,2020,2020,...
,,,総人口,総人口（男）,総人口（女）,...
R01100,北海道,札幌市,1973395,918682,1054713,...
R01202,北海道,函館市,251084,113965,137119,...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The 4 Pitfalls:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;3-Row Composite Header&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Row 0: Statistical indicator codes (&lt;code&gt;A1101&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Row 1: Survey survey years (&lt;code&gt;2020&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Row 2: Human-readable Japanese names (&lt;code&gt;総人口&lt;/code&gt; = Total Population)&lt;/li&gt;
&lt;li&gt;Running &lt;code&gt;pd.read_csv()&lt;/code&gt; treats rows 1 and 2 as data, coercing every integer column into an &lt;code&gt;object&lt;/code&gt; dtype.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "R" Prefix and Zero-Dropping&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Standard Japanese municipality codes are 5 digits (JIS X 0402). For instance, Sapporo is &lt;code&gt;01100&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The raw data prefixes an "R" (&lt;code&gt;R01100&lt;/code&gt;). If parsed as numeric, it drops the leading zero and becomes &lt;code&gt;1100&lt;/code&gt;, breaking relational joins with map shapefiles and corporate registries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encoding Quirks&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Distributed in &lt;code&gt;CP932&lt;/code&gt; (Windows-31J / Shift-JIS).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raw Counts Without Relative Metrics&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;The raw data has total population and habitable area, but lacks pre-calculated density or demographic ratios essential for GIS and spatial modeling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  2. Step 1: Automated Fetch Pipeline
&lt;/h2&gt;

&lt;p&gt;We start by fetching the raw dataset directly from NSTAC's server. We enforce explicit timeouts and an authentic User-Agent to avoid connection blocks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;RAW_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;RAW_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;RAW_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RAW_DIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SSDSE-A-2026.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;DATA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.nstac.go.jp/files/SSDSE-A-2026.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_raw_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;RAW_FILE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;File already exists: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;RAW_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RAW_FILE&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Downloading from &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;DATA_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATA_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RAW_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Downloaded: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;RAW_FILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;RAW_FILE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;st_size&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; bytes)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RAW_FILE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Step 2: Unpacking Multi-Headers &amp;amp; Normalizing Codes
&lt;/h2&gt;

&lt;p&gt;To handle the 3-row header, we parse the first 3 rows separately to build clean column names, and then read the data body starting from row 4.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clean_ssdse_dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csv_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Parse header metadata
&lt;/span&gt;    &lt;span class="n"&gt;df_meta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csv_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cp932&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nrows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;codes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df_meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;
    &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df_meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;

    &lt;span class="n"&gt;columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;municipality_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prefecture&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;municipality_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codes&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Ingest data body (explicitly enforce string types on key columns to preserve leading zeros)
&lt;/span&gt;    &lt;span class="n"&gt;dtype_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;csv_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cp932&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;skiprows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dtype_dict&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Clean municipality codes: Strip 'R' and zero-pad to exactly 5 digits
&lt;/span&gt;    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;municipality_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;municipality_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;R&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zfill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 4. Safe numerical coercion (convert '-' or missing symbols to 0)
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;
        &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coerce&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cleaned &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; municipalities with &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; columns.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Step 3: Engineering 10 Essential Demographic &amp;amp; Spatial KPIs
&lt;/h2&gt;

&lt;p&gt;Roughly 70% of Japan is mountainous terrain. Comparing municipal density using gross surface area heavily skews commercial and spatial evaluations. Calculating &lt;strong&gt;Habitable Population Density (可住地人口密度)&lt;/strong&gt; provides an accurate measure of living and market congestion.&lt;/p&gt;

&lt;p&gt;We calculate 10 key metrics while guarding against division-by-zero errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;enrich_kpis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Temporary zero-to-NaN conversion to prevent ZeroDivisionError
&lt;/span&gt;    &lt;span class="n"&gt;pop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;総人口&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;area_tot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;総面積&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;area_hab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;可住地面積&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hholds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;世帯数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;kpis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Spatial densities (Persons per km2)
&lt;/span&gt;    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_pop_density_total&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;総人口&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;area_tot&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_pop_density_habitable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;総人口&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;area_hab&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Age demographic ratios (%)
&lt;/span&gt;    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_aging_rate_pct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;65歳以上人口&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_late_elderly_rate_pct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;75歳以上人口&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_youth_rate_pct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;15歳未満人口&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_working_age_rate_pct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;15～64歳人口&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Single-person household ratio (%)
&lt;/span&gt;    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_single_household_ratio_pct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;単独世帯数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;hholds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Net migration &amp;amp; natural balance (persons)
&lt;/span&gt;    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_net_migration_persons&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;転入者数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;転出者数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_natural_change_persons&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;出生数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;死亡数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Healthcare capacity (clinics + hospitals per 1,000 residents)
&lt;/span&gt;    &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kpi_medical_facilities_per_1k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;一般診療所数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;一般病院数&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fillna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Place KPIs directly next to identifiers
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;kpis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:]],&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Step 4: Multi-Format Export (Excel, Parquet &amp;amp; SQLite)
&lt;/h2&gt;

&lt;p&gt;For analytical environments (DuckDB, PySpark, Polars), columnar formats like Parquet offer 10x-50x faster read speeds and built-in compression. Meanwhile, business users frequently open files in Microsoft Excel.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip for Windows Excel&lt;/strong&gt;: Saving as plain UTF-8 often triggers mojibake in Windows Excel. Always encode with &lt;code&gt;utf-8-sig&lt;/code&gt; (BOM) and use &lt;code&gt;\r\n&lt;/code&gt; line terminators.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;export_pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_dir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;out_dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 1. Windows Excel-Ready CSV (BOM-UTF8 with CRLF)
&lt;/span&gt;    &lt;span class="n"&gt;csv_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;out_dir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;japan_municipal_census_ssdse_master.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csv_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8-sig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lineterminator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. High-Performance Columnar Parquet (Snappy compression)
&lt;/span&gt;    &lt;span class="n"&gt;pq_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;out_dir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;japan_municipal_census_ssdse_master.parquet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pq_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;snappy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Indexed SQLite DB for Rapid SQL Queries
&lt;/span&gt;    &lt;span class="n"&gt;db_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;out_dir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;municipal_master.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;municipalities&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;if_exists&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CREATE INDEX IF NOT EXISTS idx_muni_code ON municipalities (municipality_code);&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Export complete across all 3 formats in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;out_dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Advanced Spatial Engineering: Bridging Census Masters with Uber H3 Hexagonal Indexing
&lt;/h2&gt;

&lt;p&gt;In modern spatial data science, joining point observations (e.g., store locations, medical clinics, real estate listings) with municipal administrative polygons is computationally expensive. Traditional GIS spatial operations like &lt;code&gt;ST_Contains&lt;/code&gt; or &lt;code&gt;gpd.sjoin&lt;/code&gt; require heavy geometric intersection math ($O(N \times M)$ complexity).&lt;/p&gt;

&lt;p&gt;To enable lightning-fast spatial joins and hexagonal clustering, we can enrich each municipality with &lt;strong&gt;Uber's H3 Discrete Global Grid System (DGGS)&lt;/strong&gt; based on municipal centroids (city hall coordinates):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;h3&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;enrich_uber_h3_indices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lat_col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latitude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lon_col&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;longitude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Assigns Uber H3 hierarchical hexagonal cells:
    - Resolution 7: ~5.16 km² (approx. municipal ward / town cluster)
    - Resolution 8: ~0.74 km² (neighborhood commercial scale)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;h3_res7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latlng_to_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lat_col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lon_col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lat_col&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lon_col&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;h3_res8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latlng_to_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lat_col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lon_col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lat_col&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lon_col&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Uber H3 is a Game-Changer for Census Analysis:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;$O(1)$ Hash Spatial Joins&lt;/strong&gt;: Instead of running heavy point-in-polygon calculations across thousands of geo-coordinates, you simply match on integer/string H3 cell IDs in DuckDB or Pandas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seamless Neighbor Traversal (&lt;code&gt;k-ring&lt;/code&gt;)&lt;/strong&gt;: Analyze surrounding demographic gravity by fetching immediate adjacent hexagons in one line: &lt;code&gt;h3.grid_disk(h3_cell, k=1)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web-Scale Interactive Mapping&lt;/strong&gt;: H3 IDs render natively in high-performance WebGL frameworks like &lt;strong&gt;deck.gl&lt;/strong&gt; and &lt;strong&gt;Kepler.gl&lt;/strong&gt; without transferring heavy GeoJSON polygon payloads.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Summary &amp;amp; Impact
&lt;/h2&gt;

&lt;p&gt;By executing this automated pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We transform an awkward 3-header Japanese government CSV into a clean &lt;strong&gt;1,741 rows × 140 columns&lt;/strong&gt; flat dataset.&lt;/li&gt;
&lt;li&gt;The 5-digit JIS municipality code is standardized, allowing effortless joins with Japan's land valuation registries, healthcare establishment directories, and GIS boundary GeoJSONs.&lt;/li&gt;
&lt;li&gt;By optionally projecting municipal coordinates into &lt;strong&gt;Uber H3 hexagonal grid cells&lt;/strong&gt;, spatial analysts unlock $O(1)$ relational joins and high-performance WebGL heatmaps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding with Japanese open data!&lt;/p&gt;

</description>
      <category>automation</category>
      <category>datascience</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What I Learned Building Multiple MCP Servers for Local LLMs (Qwen3-8B): Tool Granularity, Latency Traps, and Dogfooding</title>
      <dc:creator>Japan Open Data Lab</dc:creator>
      <pubDate>Fri, 16 Oct 2026 06:02:17 +0000</pubDate>
      <link>https://dev.to/japanopendatalab/what-i-learned-building-multiple-mcp-servers-for-local-llms-qwen3-8b-tool-granularity-latency-39lc</link>
      <guid>https://dev.to/japanopendatalab/what-i-learned-building-multiple-mcp-servers-for-local-llms-qwen3-8b-tool-granularity-latency-39lc</guid>
      <description>&lt;p&gt;Recently, I have been building a local data analysis stack pairing &lt;strong&gt;LM Studio (&lt;code&gt;Qwen3-8B&lt;/code&gt;)&lt;/strong&gt; with custom &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; servers to query and cross-analyze over 180 normalized Japanese government and corporate datasets.&lt;/p&gt;

&lt;p&gt;At first, I fell into the classic developer temptation: &lt;em&gt;"What if I build an MCP tool for everything—web scraping, stock prices, climate data, random correlation discovery, and multi-platform publishing?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, running multiple MCP servers against a local 8B model quickly exposed real-world bottlenecks that you rarely notice when using frontier cloud models.&lt;/p&gt;

&lt;p&gt;Here are the 5 biggest engineering lessons I learned from building and open-sourcing our MCP servers (&lt;a href="https://github.com/japan-opendata-lab/japan-data-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;japan-data-mcp&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/japan-opendata-lab/correlation-discovery-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;correlation-discovery-mcp&lt;/code&gt;&lt;/a&gt;)—including an unexpected plot twist at the end.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Hidden Token Tax: Why Adding More MCPs Kills Local LLM Speed
&lt;/h2&gt;

&lt;p&gt;Enabling every cool MCP server you find is the fastest way to ruin your local LLM experience.&lt;/p&gt;

&lt;p&gt;Every time you send a message, the MCP client injects the &lt;strong&gt;full JSON Schema definitions of all currently enabled tools&lt;/strong&gt; into the system prompt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1 tool definition&lt;/strong&gt;: ~150–300 tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4–5 tools enabled&lt;/strong&gt;: ~1,000 tokens (instant prompt processing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;35–40 tools enabled across 6 MCPs&lt;/strong&gt;: &lt;strong&gt;8,000–10,000+ tokens on every single turn&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On an 8B local model running with a 16k context window, 40 tools will eat half of your context window before the conversation even starts, noticeably degrading &lt;strong&gt;Time-to-First-Token (TTFT)&lt;/strong&gt;. Worse, once an 8B model sees more than ~15 tools simultaneously, its tool-selection accuracy drops and it starts looping through redundant tool calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb for 8B local models:&lt;/strong&gt; Keep the total number of simultaneously active tools under &lt;strong&gt;5 to 10&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Golden Rule of Tool Granularity: When to Merge vs. When to Split
&lt;/h2&gt;

&lt;p&gt;If we want fewer tools, should we just cram every feature into a single mega-tool? Not necessarily. Through trial and error, a clear architectural boundary emerged.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to MERGE into 1 Tool: Python-Offloaded Pipelines
&lt;/h3&gt;

&lt;p&gt;If the backend Python code can execute the entire workflow end-to-end without needing intermediate LLM reasoning, &lt;strong&gt;merge it into a single tool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, when designing &lt;a href="https://github.com/japan-opendata-lab/correlation-discovery-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;correlation-discovery-mcp&lt;/code&gt;&lt;/a&gt;, I initially considered three separate tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A "Serendipity Gacha" tool to pick random dataset pairs&lt;/li&gt;
&lt;li&gt;A Pearson correlation ($r$) calculator tool&lt;/li&gt;
&lt;li&gt;A lateral-thinking prompt injector&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When separated, the 8B model had to write complex multi-table &lt;code&gt;JOIN&lt;/code&gt; and statistical SQL queries in between tool calls—frequently failing on column mismatches or granularity differences.&lt;/p&gt;

&lt;p&gt;By merging all three into &lt;strong&gt;one unified tool (&lt;code&gt;discover_correlations&lt;/code&gt;)&lt;/strong&gt; powered by an in-memory DuckDB + Python engine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mode="pair"&lt;/code&gt;&lt;/strong&gt;: Computes exact Pearson $r$, linear regression ($R^2$), top/bottom records, and residual Z-score outliers in &lt;strong&gt;0.005 seconds&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mode="find_drivers"&lt;/code&gt;&lt;/strong&gt;: Scans all 180+ joinable tables against a target metric to rank top positive/negative drivers in &lt;strong&gt;0.056 seconds&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mode="serendipity"&lt;/code&gt;&lt;/strong&gt;: Automatically discovers surprising cross-domain correlations ($|r| \ge 0.5$) and extreme anomalies in &lt;strong&gt;0.136 seconds&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Zero SQL errors from the LLM, and 100% of the 8B model's &lt;code&gt;&amp;lt;think&amp;gt;&lt;/code&gt; budget is spent on &lt;em&gt;interpreting why&lt;/em&gt; the correlation exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to SPLIT into Multiple Tools: Sequential Guardrails
&lt;/h3&gt;

&lt;p&gt;Conversely, our core catalog server &lt;a href="https://github.com/japan-opendata-lab/japan-data-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;japan-data-mcp&lt;/code&gt;&lt;/a&gt; exposes &lt;strong&gt;4 distinct tools&lt;/strong&gt; instead of 1:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;list_japan_datasets&lt;/code&gt; (Search the catalog)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;describe_japan_dataset&lt;/code&gt; (Inspect exact column names &amp;amp; types)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;query_japan_sql&lt;/code&gt; (Execute read-only SQL)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_japan_company_profile&lt;/code&gt; (360° multi-table company lookup shortcut)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why not merge the first three? Because &lt;strong&gt;the LLM cannot write a valid SQL query in Step 3 until it has seen the exact column names from Step 2.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When merged into a single tool, an 8B model tends to skip schema inspection and immediately hallucinate table and column names (&lt;code&gt;SELECT * FROM hospitals&lt;/code&gt;). Splitting &lt;code&gt;list&lt;/code&gt; → &lt;code&gt;describe&lt;/code&gt; → &lt;code&gt;query&lt;/code&gt; acts as a natural &lt;strong&gt;behavioral guardrail&lt;/strong&gt; that guides the model through the correct sequential workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Why &lt;code&gt;Sequential Thinking MCP&lt;/code&gt; Backfires on &lt;code&gt;Qwen3-8B&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Sequential Thinking MCP&lt;/code&gt; is popular for boosting reasoning in smaller models, but on &lt;strong&gt;&lt;code&gt;Qwen3-8B&lt;/code&gt;&lt;/strong&gt;, it actually hurts performance.&lt;/p&gt;

&lt;p&gt;Why? Because &lt;code&gt;Qwen3-8B&lt;/code&gt; already features a powerful native &lt;code&gt;&amp;lt;think&amp;gt;...&amp;lt;/think&amp;gt;&lt;/code&gt; reasoning block trained directly into its weights. Adding an external thinking tool creates a &lt;strong&gt;double-thinking loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The model thinks inside its native &lt;code&gt;&amp;lt;think&amp;gt;&lt;/code&gt; block.&lt;/li&gt;
&lt;li&gt;It calls the &lt;code&gt;sequentialthinking&lt;/code&gt; MCP tool to output the exact same thoughts.&lt;/li&gt;
&lt;li&gt;It receives the tool response and enters another &lt;code&gt;&amp;lt;think&amp;gt;&lt;/code&gt; block.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Latency and token usage double with zero improvement in analytical quality. Let native reasoning models think natively, and reserve MCP strictly for external data and deterministic computation.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Security Hardening Checklist for Public Data MCPs
&lt;/h2&gt;

&lt;p&gt;If you are open-sourcing MCP servers that connect to local databases (like DuckDB or Parquet files), treat the LLM as an untrusted caller:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Strict Read-Only DuckDB Sandbox&lt;/strong&gt;: Always open connections with &lt;code&gt;read_only=True&lt;/code&gt;, and immediately lock the configuration:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SET enable_external_access=false&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SET lock_configuration=true&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This physically prevents SQL injection or hallucinated queries from reading arbitrary files on the host OS (&lt;code&gt;read_csv_auto('/etc/...')&lt;/code&gt;) or writing files (&lt;code&gt;COPY ... TO&lt;/code&gt;).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Path Traversal Protection&lt;/strong&gt;: Validate every output path using &lt;code&gt;Path.resolve().relative_to(base_dir)&lt;/code&gt; and never expose file deletion capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indirect Prompt Injection Boundaries&lt;/strong&gt;: Strip control tokens (&lt;code&gt;&amp;lt;|im_start|&amp;gt;&lt;/code&gt;, &lt;code&gt;[INST]&lt;/code&gt;) from external text and wrap untrusted strings in &lt;code&gt;&amp;lt;untrusted_data&amp;gt;...&amp;lt;/untrusted_data&amp;gt;&lt;/code&gt; tags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git History Hygiene&lt;/strong&gt;: Run a pre-push regex check (&lt;code&gt;git grep&lt;/code&gt;) to ensure zero local OS usernames, absolute paths, or API keys ever enter commit history.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  5. The Plot Twist: "Building Free MCPs Won't Make a Dime... Wait."
&lt;/h2&gt;

&lt;p&gt;Halfway through planning five different open-source MCP servers, I laughed and thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Wait—even if I build a bunch of free MCP tools and put them on GitHub, that alone won't generate a single dollar of revenue!"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is very easy for solo founders and data engineers to fall into the &lt;strong&gt;"Tool-Building Trap"&lt;/strong&gt;—procrastinating on actual product distribution by endlessly polishing developer tooling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But then something unexpected happened.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I hooked up &lt;code&gt;Qwen3-8B&lt;/code&gt; to our MCP servers and started running real natural-language queries and automated correlation scans across our commercial dataset catalog, &lt;strong&gt;the LLM immediately exposed structural flaws in our own data.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, when I asked the local LLM to rank the top 5 government procurement awards from our &lt;code&gt;procurement&lt;/code&gt; table, the model failed to sort by &lt;code&gt;amount_jpy&lt;/code&gt;. Why? Because when it ran &lt;code&gt;describe_japan_dataset&lt;/code&gt;, it discovered that our ingestion pipeline had accidentally concatenated the winning supplier name, contract date, and award amount into a single text column (&lt;code&gt;address_line1: "Supplier: X / Date: YYYY-MM-DD / Award: 1000000 JPY"&lt;/code&gt;), forcing the poor 8B model to write monstrous &lt;code&gt;SUBSTR()&lt;/code&gt; and &lt;code&gt;INSTR()&lt;/code&gt; SQL queries just to extract numbers!&lt;/p&gt;

&lt;p&gt;Our automated row-count tests had passed 100%, completely missing the usability flaw. &lt;strong&gt;Dogfooding our datasets through a local 8B model via MCP turned out to be the ultimate QA litmus test:&lt;/strong&gt; &lt;em&gt;If an 8B model can't query a table cleanly on the first try, human analysts and paying API customers won't want to use it either.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Check Out the Open-Source Repos
&lt;/h2&gt;

&lt;p&gt;If you are working with DuckDB, Parquet, CSVs, or Japanese public/corporate datasets, feel free to try or fork our MCP servers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;strong&gt;&lt;a href="https://github.com/japan-opendata-lab/correlation-discovery-mcp" rel="noopener noreferrer"&gt;correlation-discovery-mcp&lt;/a&gt;&lt;/strong&gt; — Ultra-fast (0.005s–0.136s) Pearson correlation scanner, driver ranking, and residual outlier detector for any DuckDB / Parquet / CSV directory.&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;&lt;a href="https://github.com/japan-opendata-lab/japan-data-mcp" rel="noopener noreferrer"&gt;japan-data-mcp&lt;/a&gt;&lt;/strong&gt; — Official MCP server for 100+ normalized Japanese government, demographic, procurement, and corporate datasets (also available via &lt;a href="https://rapidapi.com/organization/japan-opendata-lab" rel="noopener noreferrer"&gt;RapidAPI&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>llm</category>
      <category>python</category>
      <category>duckdb</category>
    </item>
    <item>
      <title>MCP Explained in 5 Layers: How I Connected 10.16M Records to AI (and Why It's a Blue Ocean)</title>
      <dc:creator>Japan Open Data Lab</dc:creator>
      <pubDate>Thu, 15 Oct 2026 13:50:41 +0000</pubDate>
      <link>https://dev.to/japanopendatalab/mcp-explained-in-5-layers-how-i-connected-1016m-records-to-ai-and-why-its-a-blue-ocean-4gi</link>
      <guid>https://dev.to/japanopendatalab/mcp-explained-in-5-layers-how-i-connected-1016m-records-to-ai-and-why-its-a-blue-ocean-4gi</guid>
      <description>&lt;p&gt;Every week, big tech companies spend hundreds of millions of dollars competing over LLM benchmarks. As indie developers and builders, fighting on that turf is a losing game.&lt;/p&gt;

&lt;p&gt;Instead of building another thin chat wrapper, I recently tackled a problem Silicon Valley giants will never touch: cleaning &lt;strong&gt;155 messy Japanese public datasets (10.16 million records)&lt;/strong&gt; and connecting them directly to AI agents via &lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt; in a server called &lt;code&gt;japan-data-mcp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Building this—and achieving a top quality score on MCP directories—gave me a dead-simple framework for understanding &lt;strong&gt;what MCP actually is, how it kills hallucinations, and why MCP is the best blue ocean for developers today.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is the whole blueprint.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔌 What is MCP in One Sentence?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP is the universal "USB Type-C port" that plugs external tools and data warehouses directly into an AI's brain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before MCP, connecting an LLM to a database or local tool required custom glue code for every provider. With MCP, you write a server once and plug it into Claude Desktop, Cursor, Windsurf, Cline, or your own local agent.&lt;/p&gt;

&lt;p&gt;It transforms AI from a chatbot relying on fuzzy training memory into an &lt;strong&gt;autonomous worker using deterministic tools&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ The 5 Roles of a Production AI System
&lt;/h2&gt;

&lt;p&gt;A real-world AI system is never just an LLM doing everything alone. Think of it like a &lt;strong&gt;company organization&lt;/strong&gt; (or &lt;em&gt;Mega Man&lt;/em&gt; equipping special weapon cassettes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-------------------------------------------------------------------+
| [5] Reception Desk (UI / Host: Claude Desktop, Cursor, Mobile UI) |
+-------------------------------------------------------------------+
                                 |
+-------------------------------------------------------------------+
| [4] SOP / Guidelines (System Prompt: "Never guess. Use tools.")   |
+-------------------------------------------------------------------+
                                 |
+-------------------------------------------------------------------+
| [1] The Brain (LLM: Claude, Gemini, local Gemma)                  |
|     "Brilliant new-grad elite, but knows zero internal facts"     |
+-------------------------------------------------------------------+
                                 |  &amp;lt;-- MCP (USB Type-C Port)
+-------------------------------------------------------------------+
| [3] Hands &amp;amp; Tools (MCP Server: Calculator, Query Engine, Alerts)  |
+-------------------------------------------------------------------+
                                 |
+-------------------------------------------------------------------+
| [2] Memory &amp;amp; Archive (10.16M-Row DB, or a local Markdown file)    |
+-------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Brain (LLM: Claude, Gemini, Gemma)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;brilliant new-grad elite&lt;/strong&gt; trained with billions of dollars. Great at reasoning and language, but knows nothing about your company's internal data or today's exact numbers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Memory &amp;amp; Archive (Databases &amp;amp; Files)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;official ledger and manual&lt;/strong&gt; in the office cabinet. This could be my 155 cleaned public datasets (10.16M records) or a single Markdown file on your smartphone.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Hands &amp;amp; Tools (MCP &amp;amp; External Tools)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;calculator, search terminal, telephone, or special weapon&lt;/strong&gt; you hand to the new hire so they can actually query, calculate, and trigger actions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The SOP / Instruction Memo (System Prompt)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The manager's strict rule: &lt;em&gt;"Look at the ledger (#2) and use the calculator (#3). Never guess from memory."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Reception Desk (UI / Client)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The counter that humans touch (Cursor, Claude Desktop, or a mobile app).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎯 Why Hallucinations Physically Disappear
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bare LLM (Without MCP):&lt;/strong&gt;
Like a &lt;strong&gt;teacher standing at the podium empty-handed&lt;/strong&gt;, with no textbook and no calculator. When asked for specific figures, they improvise a plausible-sounding lie from fuzzy memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM + MCP:&lt;/strong&gt;
You put the official ledger (&lt;strong&gt;#2&lt;/strong&gt;) on the desk, hand them a calculator (&lt;strong&gt;#3&lt;/strong&gt;), and forbid guessing (&lt;strong&gt;#4&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the AI is reduced to &lt;strong&gt;pointing at the official ledger and reading out the calculator's output&lt;/strong&gt;, factual hallucinations become physically impossible.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 The 3 Archetypes of MCP Servers
&lt;/h2&gt;

&lt;p&gt;You don't need millions of rows of data to build an MCP server. They fall into three distinct patterns:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Backed By&lt;/th&gt;
&lt;th&gt;Best Use Cases&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1. Data-Backed MCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Massive, pre-cleaned database (e.g., &lt;code&gt;japan-data-mcp&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;High-moat B2B intelligence, market &amp;amp; government research&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2. Stateful Memory MCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Starts with an &lt;strong&gt;empty file&lt;/strong&gt; (Markdown / SQLite) that the AI updates&lt;/td&gt;
&lt;td&gt;Personal AI companions, contradiction-free novel writing, TRPGs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3. Action / Remote MCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Zero state; triggers OS clicks, APIs, emails, Slack alerts&lt;/td&gt;
&lt;td&gt;Workflow automation, RPA replacement&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🌊 Why MCP is the Ultimate Blue Ocean for Builders
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sell Pickaxes, Avoid the LLM War:&lt;/strong&gt;
Building "The Brain" (#1) costs billions. Building MCP tools (#3) means whichever LLM wins next week, your tool plugs right into it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Big Tech Won't Clean "Dirty" Local Data:&lt;/strong&gt;
Japanese government open data is full of merged Excel cells, legacy Shift_JIS encodings, and imperial era dates (Showa/Heisei/Reiwa). Google and Anthropic will never unmerge those cells or join them via 13-digit corporate numbers and 5-digit municipal codes. &lt;strong&gt;Cleaning and owning the messy ledger (#2) gives you an unbreakable moat.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;B2B Expense Budgets vs. Consumer Pocket Change:&lt;/strong&gt;
An MCP server that turns 3 days of manual procurement or market research into a 10-second query directly replaces overtime and consulting fees—making it an easy corporate expense.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🚀 What's Live Now &amp;amp; 3 Next-Gen Ideas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What We Built: &lt;code&gt;japan-data-mcp&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;We cleaned and normalized &lt;strong&gt;155 official datasets (10.16M+ records)&lt;/strong&gt;—including 100% of disclosed GEPS central government procurement awards (2020–2026), 44 years of land price valuations (1983–2026), and all 1,741 municipalities—and exposed them via MCP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"japan-data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"japan-data-mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"RAPIDAPI_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_API_KEY"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open Parquet Samples (Hugging Face):&lt;/strong&gt; &lt;a href="https://huggingface.co/datasets/japan-opendata/japan-official-data-megabank-showcase" rel="noopener noreferrer"&gt;japan-official-data-megabank-showcase&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production API Hub (RapidAPI):&lt;/strong&gt; &lt;a href="https://rapidapi.com/organization/japan-opendata-lab" rel="noopener noreferrer"&gt;Japan Open Data Lab&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3 Ideas I'm Exploring Next
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;B2B Action MCPs:&lt;/strong&gt; Combining our 10.16M-row database with Action MCPs to auto-detect new government tenders, notify teams on Slack, and draft initial proposals from historical winning bid prices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Cost Offline AI Companion on Pixel:&lt;/strong&gt; Pairing an on-device LLM (like Gemma) with a Stateful Memory MCP that appends daily memories to local Markdown files—100% offline, zero API cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contradiction-Free "Novelist &amp;amp; TRPG" MCP:&lt;/strong&gt; Letting the AI manage character sheets, world lore, and timelines via MCP so long-form stories and RPG campaigns never suffer from plot holes.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;What kind of MCP server are you building (or planning to build) next? Data-backed, Stateful Memory, or Action-oriented? Let's discuss in the comments! 👇&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>claude</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Analyzing 40 Years of Japanese Public Open Data in 3 Minutes with DuckDB (No API Keys, In-Memory Parquet)</title>
      <dc:creator>Japan Open Data Lab</dc:creator>
      <pubDate>Thu, 15 Oct 2026 01:11:23 +0000</pubDate>
      <link>https://dev.to/japanopendatalab/analyzing-40-years-of-japanese-public-open-data-in-3-minutes-with-duckdb-no-api-keys-in-memory-52k1</link>
      <guid>https://dev.to/japanopendatalab/analyzing-40-years-of-japanese-public-open-data-in-3-minutes-with-duckdb-no-api-keys-in-memory-52k1</guid>
      <description>&lt;h2&gt;
  
  
  The Hidden Goldmine (and Nightmare) of Japan's Open Data
&lt;/h2&gt;

&lt;p&gt;Japan’s government ministries publish massive amounts of open public data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-billion-dollar national procurement contracts (Digital Agency / GEPS)&lt;/li&gt;
&lt;li&gt;44-year historical nationwide land valuation benchmarks (MLIT)&lt;/li&gt;
&lt;li&gt;Over 5 million corporate registry records (National Tax Agency)&lt;/li&gt;
&lt;li&gt;470,000+ registered medical and eldercare facilities (MHLW)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For quantitative hedge funds, real estate investors, and AI researchers, this is institutional-grade economic intelligence.&lt;/p&gt;

&lt;p&gt;However, working with raw Japanese government datasets is notoriously painful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Shift_JIS Encodings&lt;/strong&gt;: Instant mojibake (garbled characters) in standard Python environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imperial Eras&lt;/strong&gt;: Dates like &lt;em&gt;Reiwa 5&lt;/em&gt; or &lt;em&gt;Heisei 28&lt;/em&gt; break standard time-series models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merged Cells &amp;amp; Non-Standard Layouts&lt;/strong&gt;: Handcrafted Excel tables that crash pandas readers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disparate Identifiers&lt;/strong&gt;: Cross-ministry entity matching usually requires painful entity resolution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At &lt;strong&gt;Japan Open Data Lab&lt;/strong&gt;, we mechanically eliminated all of these quirks. We converted &lt;strong&gt;155+ official datasets (10.16M+ records)&lt;/strong&gt; into US Federal &amp;amp; SEC 24-column snake_case schema, unified under the official &lt;strong&gt;13-digit National Tax Agency Corporate Number&lt;/strong&gt; and &lt;strong&gt;5-digit JIS Municipal Code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We published lightweight showcase samples on Hugging Face and built a &lt;strong&gt;3-Minute Google Colab Recipe&lt;/strong&gt; so you can query them right now in your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://colab.research.google.com/github/japan-opendata-lab/japan-official-data-megabank/blob/main/notebooks/japan_open_data_in_3_minutes.ipynb" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcolab.research.google.com%2Fassets%2Fcolab-badge.svg" alt="Open In Colab" width="117" height="20"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Zero-Download In-Memory Queries with DuckDB
&lt;/h2&gt;

&lt;p&gt;Using DuckDB's HTTP Parquet reader, you can analyze multi-megabyte remote datasets in milliseconds without local storage overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;duckdb plotly pandas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Top Government Contractors (Digital Agency GEPS)
&lt;/h3&gt;

&lt;p&gt;Query all central government procurement awards (2020-2026, ~285,000 records) in 1 line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;duckdb&lt;/span&gt;

&lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;duckdb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://huggingface.co/datasets/japan-opendata/japan-official-data-megabank-showcase/resolve/main/data/japan_public_procurement_sample_5k.parquet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    SELECT 
        legal_name AS vendor_name,
        corporate_number,
        COUNT(*) AS total_contracts,
        ROUND(SUM(capital_amount_jpy) / 1e8, 2) AS total_award_100m_yen
    FROM read_parquet(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)
    WHERE legal_name IS NOT NULL
    GROUP BY legal_name, corporate_number
    ORDER BY total_award_100m_yen DESC
    LIMIT 5
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;df&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Cross-Table JOIN on 13-Digit Corporate Key
&lt;/h3&gt;

&lt;p&gt;Cross-link government tender winners with the National Tax Agency corporate registry using standard SQL JOINs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;proc_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://huggingface.co/datasets/japan-opendata/japan-official-data-megabank-showcase/resolve/main/data/japan_public_procurement_sample_5k.parquet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;corp_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://huggingface.co/datasets/japan-opendata/japan-official-data-megabank-showcase/resolve/main/data/japan_corporate_invoices_sample_5k.parquet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    SELECT 
        p.legal_name,
        p.corporate_number,
        c.prefecture_en AS hq_prefecture,
        c.city_ja AS hq_city,
        ROUND(SUM(p.capital_amount_jpy) / 1e6, 2) AS total_million_jpy
    FROM read_parquet(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;proc_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;) p
    JOIN read_parquet(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;corp_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;) c
        ON p.corporate_number = c.corporate_number
    GROUP BY p.legal_name, p.corporate_number, c.prefecture_en, c.city_ja
    ORDER BY total_million_jpy DESC
    LIMIT 5
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;df&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Historical Benchmark Land Valuations (MLIT 44-Year Archive)
&lt;/h3&gt;

&lt;p&gt;Query official land evaluation points across Japan from 1983 to 2026 (~1.1M records):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;land_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://huggingface.co/datasets/japan-opendata/japan-official-data-megabank-showcase/resolve/main/data/japan_land_prices_sample_5k.parquet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;land_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    SELECT 
        area_name_local AS location,
        city,
        current_value AS land_price_yen_per_sqm,
        yoy_change_pct,
        event_date AS valuation_year
    FROM read_parquet(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;land_url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)
    WHERE current_value IS NOT NULL
    ORDER BY current_value DESC
    LIMIT 5
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;df&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;land_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Interactive Playground (Google Colab)
&lt;/h2&gt;

&lt;p&gt;Run the full interactive benchmark with Plotly charts in under 3 minutes directly in your browser:&lt;br&gt;&lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://colab.research.google.com/github/japan-opendata-lab/japan-official-data-megabank/blob/main/notebooks/japan_open_data_in_3_minutes.ipynb" rel="noopener noreferrer"&gt;Open In Google Colab&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Production API &amp;amp; Full Datasets
&lt;/h2&gt;

&lt;p&gt;Looking for complete production feeds (10.16M+ rows, 44-year depth, and daily sync)?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RapidAPI Hub&lt;/strong&gt;:
&lt;a href="https://rapidapi.com/organization/japan-opendata-lab" rel="noopener noreferrer"&gt;https://rapidapi.com/organization/japan-opendata-lab&lt;/a&gt;
Includes a &lt;strong&gt;Free Tier (BASIC $0)&lt;/strong&gt; and high-frequency commercial tiers up to &lt;strong&gt;MEGA ($499/mo)&lt;/strong&gt; with direct DuckDB raw SQL execution (&lt;code&gt;POST /api/v1/query&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude / Cursor MCP Server&lt;/strong&gt;:
&lt;a href="https://github.com/japan-opendata-lab/japan-data-mcp" rel="noopener noreferrer"&gt;https://github.com/japan-opendata-lab/japan-data-mcp&lt;/a&gt;
Smithery 100/100 Quality Certified for Claude Desktop &amp;amp; Cursor IDE.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python SDK&lt;/strong&gt;:
&lt;code&gt;pip install git+https://github.com/japan-opendata-lab/japan-official-data-megabank&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>duckdb</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
