データ分析
2025/10/22
森田 和登

体裁が崩れたExcelファイルをS3→Databricksでテーブルに変換する

A1から始まらない・空白セルが多いなど体裁が崩れたExcelファイルを、S3とUnity CatalogのVolumeを経由してDatabricksで読み込み、Pandasで加工してDeltaテーブル化する手順を解説!業務Excelを安定したデータパイプラインに変換する方法を紹介します。

1 はじめに

業務で配られる Excel は「先頭がA1ではない」「空白セルが多い」「見出しが複数段」など、そのままではCSV化できないような「人間向けのレイアウト」がよくあります。


本記事では、そうした Excel を S3 → (Unity Catalog の) Volume → Databricks 経由で安全に読み込み、構造化テーブル(Delta)として保存するまでの手順を解説します。


2 使用するExcelファイル

今回使うExcelファイルは、estatから取得した「消費者物価指数(中分類)」のデータを使います。




 


画像のように、セルの折りたたみ(A1から始まらない)や余白が多く、素直なCSV化は難しい体裁です。



 


今回は、以下のようなテーブルを作成し、DatabricksにDeltaテーブルとして保存することを目指します。


・年月:2025-09 のような月粒度(保存時は DATE 型で各月の1日として保持)


・地域:東京都区部 のような string型


・生鮮食品の消費者物価指数:28.8 のような double型



3 前提

Databricksの権限


・Unity Catalog が有効なワークスペース


・必要権限の例:CREATE STORAGE CREDENTIAL / CREATE EXTERNAL LOCATION / CREATE VOLUME など(管理者想定)



S3は“外部ロケーション”として接続済み


・外部ロケーションは Storage Credential(IAMロールなど)S3のURL を結びつける UC オブジェクトです。


・追加済みの外部ロケーションはsystem.information_schema.external_locationsで確認できます。



SELECT *
FROM system.information_schema.external_locations;


4 STEP1: Databricksの外部ボリュームにExcelファイルの置き場を用意する

外部ボリューム外部ロケーション配下にを作ると、S3 上の特定ディレクトリを /Volumes/<catalog>/<schema>/<volume>/... で扱えるようになります。



-- 1. どのスキーマに作るかを指定(自分の環境に合わせて変更してください)
USE CATALOG your_catalog;
USE SCHEMA your_schema;

-- 2. 外部ボリュームを作成(外部ロケーションに登録したS3バケットのサブディレクトリ)
CREATE EXTERNAL VOLUME your_catalog.your_schema.vol_excel_ci
LOCATION '{外部ロケーションに登録したバケットのS3 URI}/sample_excel/';


確認するクエリ例:



SHOW VOLUMES IN your_catalog.your_schema;
DESCRIBE VOLUME your_catalog.your_schema.vol_excel_ci;


5 STEP2: Pythonノートブックで読み込む(pandas & openpyxl)

Databricksで新規ノートブックを作成してください。


pandas.read_excel で、Excelの任意シートを DataFrame に読み込むことができます。.xlsx には openpyxl を使います。



# openpyxlをインストール
%pip install openpyxl

import pandas as pd

excel_path = "/Volumes/{your_volume_path}/{your_file_name}.xlsx"
df = pd.read_excel(
excel_path,
sheet_name="bm01-2", # ファイルに合わせて変更
engine="openpyxl"
)


どんなふうに読み込まれているか確認してみます。



# 正常に読み込めているか確認する
df.head(20)


画像のように、ExcelのセルがそのままDataframeとして読み込まれています。



 


ここから欲しい情報(年月・地域・生鮮食品のCI)だけを抽出したDataframeを作成します。


今回のファイルでは、見出しの余白をスキップして15行目(=0始まりで14)以降がデータ、 列は「年月=I列」「地域=K列」「生鮮食品CI=T列」に当たるため、以下のように切り出しました。



# Excelと行番号、列番号がズレていることに注意する
df_ci = df.iloc[14:683, [8, 10, 19]].copy()

# 欲しい列名をリネーム
df_ci.columns = ["month", "region", "ci_生鮮食品"]

# データ型を整形する
df_ci["month"] = df_ci["month"].astype(str)
df_ci["region"] = df_ci["region"].astype(str)
df_ci["ci_生鮮食品"] = pd.to_numeric(df_ci["ci_生鮮食品"], errors="coerce") # 数値化(変換不可はNaN)

# "1970年1月" などを datetime → 月単位の Period[M] に
df_ci["month"] = (
pd.to_datetime(df_ci["month"].astype(str).str.strip(),
format="%Y年%m月", errors="coerce")
.dt.to_period("M")
)

df_ci.head()


Excelの行・列番号とDataframeの行・列番号がズレていることがよくあるので、地道に調整していく必要があります。


これで、以下のようなDataframeが作成されました。




6 STEP3: Deltaテーブルとして保存する

Pandas.DataFrameをsparkのDataFrameに変換した後で、Deltaテーブルとして保存します。



# Deltaテーブルとして保存する
spark_df = spark.createDataFrame(df_ci)
table_full_path = f"your_catalog.your_schema.your_table_name"

# Deltaテーブルとして保存(上書き)
spark_df.write \\
.mode("overwrite") \\
.option("overwriteSchema", "true") \\
.saveAsTable(table_full_path)

print(f"{table_full_path}にDeltaテーブルとして保存完了")


指定したカタログ.スキーマにテーブルが保存されているはずです。



7 おわりに

上記の手順で、体裁が整っていないExcelファイルをS3 → 外部ボリューム → Databricks経由で、Pythonノートブックで加工し、Deltaテーブルとして保存することができました。


今回のような“人が読むためのExcel”でも、取り込み口を整えれば安定して回るパイプラインにできます。ぜひ自社の他のExcel資産にもこの型を当てはめ、徐々に標準化していってください。


New call-to-action