本記事では、FAO(国連食糧農業機関)の「食料価格指数」と、世界銀行(World Bank)の「エネルギー価格(Pink Sheet)」を活用し、Pythonでデータ取得から整形・可視化・相関分析までを一貫して再現します。
実際の統計データを扱いながら、穀物価格と原油価格の関係を分析し、相関係数0.877という高い連動性を確認。
食料とエネルギーがどのように“同じ波”で動くかを、コードとグラフで解き明かします。
本記事の内容はすべてPythonで再現可能です。
もし「統計分析やデータ可視化を基礎から学びたい」という方は、
👉 テックアカデミーのデータサイエンスコース
ようなオンライン講座で学んでおくと、この記事の再現がスムーズです。
概要
この記事では、FAO(国連食糧農業機関)の Food Price Index と、世界銀行(World Bank)の Commodity Price Data(Pink Sheet) を用い、Pythonでデータ取得・整形・可視化・相関分析を再現します。
メイン記事:食料価格とエネルギー価格の相関構造を探る(分析結果・経済的インサイトはこちら)
使用データ
データ名 | 提供機関 | URL | 更新頻度 | 備考 |
---|---|---|---|---|
FAO Food Price Index | FAO (United Nations) | FAO公式サイト | 月次 | 穀物・油脂・乳製品・砂糖・肉(2014–2016=100) |
World Bank Commodity Prices (“Pink Sheet”) | The World Bank | World Bank公式サイト | 月次 | 原油(Brent/WTI/Dubai)、天然ガスほか |
これから紹介するコードは、すべてpandas・matplotlib・numpyなどの主要ライブラリで動作します。
Pythonの環境構築やライブラリの基本を学びたい場合は、
テックアカデミーのデータサイエンスコースでデータ分析を体系的に学ぶと
と、分析実装まで一気に理解できるのでおすすめです。
1. ライブラリの準備
import pandas as pd import matplotlib.pyplot as plt import numpy as np
2. 食料データの取得方法(ステップバイステップ)
ゴール
-
FAOのカテゴリ別・月次データ(穀物/油脂/乳製品/砂糖/肉)をCSVで入手
-
2014–2016年=100 の名目指数を利用
-
日付を YYYY-MM-01(各月1日)に統一し、エネルギーデータと結合可能に整形
手順
-
FAO公式ページを開く
→ FAO Food Price Index ページへ。 -
ダウンロードセクション
→ ページ下部の “Download datasets” を確認。 -
月次CSVを選択
→ “CSV: Nominal indices from 1990 onwards (monthly)” をクリック。
→food_price_indices_data_*.csv
(例:food_price_indices_data_oct25.csv
)が保存されます。 -
内容を確認(代表列)
-
Date
(YYYY-MM形式) -
Food Price Index
(総合) -
Cereals
/Oils
/Dairy
/Sugar
/Meat
※版によりMeat Price Index
のような表記ゆれあり
-
-
基準と頻度
-
基準:2014–2016=100(名目)
-
頻度:月次(長期比較向き)
-
データ整形のポイント
-
FAOは
YYYY-MM
表記 →YYYY-MM-01
に正規化しておくと結合が楽。 -
最新月の確定タイミングが世界銀行とずれることがあるため、共通月のみの
inner join
が安全。
整形コード(FAO)
import pandas as pd in_csv = "food_price_indices_data_oct25.csv" # ダウンロードしたCSV名 out_csv = "fao_food_price_monthly_clean.csv" # 1) ヘッダなしで読んで、「Date」「Food Price Index」を含む行をヘッダに採用 raw = pd.read_csv(in_csv, header=None) header_row = None for i in range(min(10, len(raw))): row_vals = [str(v) for v in raw.iloc[i].tolist()] if "Date" in row_vals and "Food Price Index" in row_vals: header_row = i break if header_row is None: raise RuntimeError("ヘッダ行(Date, Food Price Index を含む行)が見つかりません。") # 2) ヘッダ適用 & 本体切り出し header = raw.iloc[header_row].tolist() df = raw.iloc[header_row+1:].reset_index(drop=True).copy() df.columns = header # 3) Unnamed列を削除 df = df.loc[:, ~df.columns.astype(str).str.startswith("Unnamed")] # 4) 列名の表記ゆれを統一 rename_map = { "Month": "Date", "Meat Price Index": "Meat", "Dairy Price Index": "Dairy", "Cereals Price Index": "Cereals", "Oils Price Index": "Oils", "Sugar Price Index": "Sugar", } df = df.rename(columns={c: rename_map.get(c, c) for c in df.columns}) # 5) 日付を YYYY-MM-01 に df["Date"] = pd.to_datetime(df["Date"], errors="coerce") df = df.dropna(subset=["Date"]).sort_values("Date") # 6) 主要列のみ keep = ["Date", "Food Price Index", "Cereals", "Oils", "Dairy", "Sugar", "Meat"] df = df[[c for c in keep if c in df.columns]].reset_index(drop=True) # 7) 保存 df.to_csv(out_csv, index=False, encoding="utf-8-sig") print("✅ FAO整形完了:", out_csv) print(df.tail())
3. FAO穀物価格の長期推移を可視化
import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl mpl.rcParams['font.family'] = 'MS Gothic' plt.style.use('ggplot') plt.rcParams['figure.figsize'] = [12, 9] # 入力 fao_csv = "fao_food_price_monthly_clean.csv" col_value = "Cereals" last_n_months = 428 # 約35年 # 読み込み df = pd.read_csv(fao_csv, parse_dates=["Date"]) df = df.sort_values("Date").dropna(subset=[col_value]) recent = df.tail(last_n_months) # 可視化 plt.figure(figsize=(9, 4.5)) plt.plot(recent["Date"], recent[col_value], linewidth=2) plt.title(f"FAO {col_value} Index (last {last_n_months} months)") plt.xlabel("Date") plt.ylabel("Index (2014–2016=100)") plt.tight_layout() plt.savefig("FAO Cereals Index.png") plt.show()
4. エネルギーデータの取得方法(世界銀行 Pink Sheet)
ゴール
-
世界銀行の Monthly Prices(Excel)から原油・天然ガスの月次データを入手
-
YYYY-MM-01
に整形し、FAOと結合できる形式に
手順(ダウンロード)
-
World Bank Commodity Markets ページへ
-
“Download historical data”(Commodity Price Data)
-
“Monthly Prices – Excel” をクリック →
CMO-Historical-Data-Monthly.xlsx
を取得
ファイル構造(“Monthly Prices” シートの典型)
-
上部:説明テキスト → 単位行(
$/bbl
,$/MMBtu
等) → シリーズコード行(CRUDE_BRENT
等) -
人間可読の列名(
Crude oil, Brent
など) -
本体データ(
1960M01
などの月次)
余分な行を飛ばし「人間可読の列名」をヘッダにするのがコツ。
Excelでの整形(簡易)
-
Power Queryで上部行を削除 → 最初の行を見出しに
-
M
を-
に置換 → 日付型に(各月1日) -
必要列のみ選択(Brent/WTI/Europe Gas/Japan LNGなど)
-
1982-01-01 より前の行は除外推奨
整形コード(World Bank, Python)
import pandas as pd import re # 設定 xlsx_path = "CMO-Historical-Data-Monthly.xlsx" sheet_name = "Monthly Prices" out_csv = "worldbank_energy_monthly_clean.csv" cutoff_date = pd.Timestamp("1982-01-01") wanted_regex = { "Crude oil, Brent": re.compile(r"crude\s*oil.*brent", re.I), "Crude oil, WTI": re.compile(r"crude\s*oil.*wti", re.I), "Crude oil, Dubai": re.compile(r"crude\s*oil.*dubai", re.I), "Natural gas, Europe": re.compile(r"natural\s*gas.*(europe|eu)", re.I), "Natural gas, U.S.": re.compile(r"natural\s*gas.*(u\.?s\.?|united\s*states)", re.I), "Liquefied natural gas, Japan": re.compile(r"(lng|liquefied\s*natural\s*gas).*(japan)", re.I), } # 1) ヘッダなしで読み込み raw = pd.read_excel(xlsx_path, sheet_name=sheet_name, header=None) # 2) データ開始行(YYYYMmm) date_pat = re.compile(r"^\d{4}[mM]\d{2}$") data_idx = None for i in range(min(200, len(raw))): v = str(raw.iat[i, 0]) if raw.shape[1] > 0 else "" if date_pat.match(v): data_idx = i break if data_idx is None: raise RuntimeError("YYYYMmm 形式の最初のデータ行が見つかりません。") # 3) 上方にヘッダ候補を探索(最大3行) def score_header(row_vals): s = " | ".join([str(x) for x in row_vals]).lower() keys = ["crude", "oil", "natural gas", "brent", "wti", "dubai", "lng", "liquefied"] return sum(k in s for k in keys) header_candidates = [] for k in range(1, 4): r = data_idx - k if r >= 0: row = raw.iloc[r].tolist() header_candidates.append((r, score_header(row))) header_row = max(header_candidates, key=lambda x: (x[1], x[0]))[0] if header_candidates else max(0, data_idx-1) header = raw.iloc[header_row].tolist() # 4) ヘッダ適用 & 切り出し df = raw.iloc[data_idx:].reset_index(drop=True).copy() df.columns = header df.rename(columns={df.columns[0]: "Date"}, inplace=True) # 5) 日付正規化(YYYYMmm → YYYY-MM-01) df = df[df["Date"].astype(str).str.match(r"^\d{4}[mM]\d{2}$", na=False)].copy() df["Date"] = pd.to_datetime( df["Date"].astype(str).str.replace("M", "m").str.replace("m", "-", regex=False), format="%Y-%m", errors="coerce" ) # 6) 欲しい列を正規表現で抽出 def find_col_by_regex(columns, pat): for c in columns: if pat.search(str(c)): return c return None found_map = {"Date": "Date"} for label, pat in wanted_regex.items(): hit = find_col_by_regex(df.columns, pat) if hit: found_map[label] = hit df_out = df[list(found_map.values())].copy() df_out.columns = list(found_map.keys()) # 7) 1982年以前を除外 → 並べ替え df_out = df_out[df_out["Date"] >= cutoff_date].sort_values("Date").reset_index(drop=True) # 8) 保存 df_out.to_csv(out_csv, index=False, encoding="utf-8-sig") print("✅ 整形完了:", out_csv) print("抽出列:", df_out.columns.tolist()) print(df_out.head(3)) print(df_out.tail(3))
5. エネルギー価格の長期推移を可視化(Brent)
import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl mpl.rcParams['font.family'] = 'MS Gothic' plt.style.use('ggplot') plt.rcParams['figure.figsize'] = [12, 9] energy_csv = "worldbank_energy_monthly_clean.csv" col_value = "Crude oil, Brent" last_n_months = 428 df = pd.read_csv(energy_csv, parse_dates=["Date"]) df = df.sort_values("Date").dropna(subset=[col_value]) recent = df.tail(last_n_months) plt.figure(figsize=(9, 4.5)) plt.plot(recent["Date"], recent[col_value], linewidth=2) plt.title(f"{col_value} Price (last {last_n_months} months)") plt.xlabel("Date") plt.ylabel("Price (US$/barrel)") plt.tight_layout() plt.savefig("Brent Crude Oil Price.png") plt.show()
6. ここから実装:統合と相関分析
入力ファイル
-
fao_food_price_monthly_clean.csv
(Date, Food Price Index, Cereals, Oils, Dairy, Sugar, Meat
) -
worldbank_energy_monthly_clean.csv
(Date, Crude oil, Brent
ほか)
自動でやること
-
Date
で inner join(共通月のみ) -
2系列の重ね合わせ(Cereals vs Brent)
-
散布図+回帰直線 & 相関係数(Pearson)
列の差し替えで他カテゴリ(Oils
など)・他エネルギー系列(Natural gas, Europe
など)にも即対応。
統合・相関分析コード(matplotlibのみ)
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 1) 読み込み fao = pd.read_csv("fao_food_price_monthly_clean.csv", parse_dates=["Date"]) energy = pd.read_csv("worldbank_energy_monthly_clean.csv", parse_dates=["Date"]) # 2) 必要列 fao = fao[["Date", "Cereals", "Food Price Index"]] energy = energy[["Date", "Crude oil, Brent"]] # 3) 結合 merged = pd.merge(fao, energy, on="Date", how="inner").sort_values("Date") merged = merged.dropna(subset=["Cereals", "Crude oil, Brent"]) # 4) 相関係数 corr = merged["Cereals"].corr(merged["Crude oil, Brent"]) print(f"相関係数(Cereals vs Brent): {corr:.3f}") # 5) 重ね合わせ(2軸) fig, ax1 = plt.subplots(figsize=(10, 5)) ax1.set_title("FAO Cereals Index vs Brent Crude Oil Price", fontsize=13) ax1.plot(merged["Date"], merged["Cereals"], label="Cereals Index", linewidth=2) ax1.set_ylabel("Cereals Index (2014–2016=100)") ax2 = ax1.twinx() ax2.plot(merged["Date"], merged["Crude oil, Brent"], label="Brent Crude", linewidth=2) ax2.set_ylabel("Brent Oil Price (US$/barrel)") fig.tight_layout() plt.savefig("Cereals vs Brent.png") plt.show() # 6) 散布図+回帰直線(numpyで単回帰) x = merged["Crude oil, Brent"].values y = merged["Cereals"].values m, b = np.polyfit(x, y, 1) plt.figure(figsize=(6, 6)) plt.scatter(x, y, alpha=0.5) plt.plot(x, m*x + b, color="red", linewidth=2) plt.title("Cereals vs Brent Crude Oil — Correlation Analysis") plt.xlabel("Brent Crude Oil Price (US$/barrel)") plt.ylabel("Cereals Index (2014–2016=100)") plt.tight_layout() plt.savefig("Cereals vs Brent Corr.png") plt.show()
7. よくあるつまずき(FAQ)
Date が見つからない/型が合わない
→ 整形段階で YYYY-MM-01 に統一。parse_dates=[“Date”] を忘れずに。
列名が違う(例:Meat Price Index)
→ FAO整形コードの rename_map を活用。
最新月が片方だけにある
→ inner join で共通月のみ分析。
長期比較で単位差が気になる
→ 変化率や基準化(初期月=100)で形の比較に切替。
以上で実装手順は完了です。
相関係数やグラフから読み取れる「世界経済の構造的な連動」については、
👉 分析編の記事で詳しく解説しています。
8. まとめ
本記事は、FAOの食料価格指数と世界銀行のエネルギー価格統計をもとに、
Python(pandas・matplotlib・numpy)を使ってデータ処理から相関分析までを再現した実装ガイドです。
公開データだけで以下の分析が可能であることを確認しました。
-
FAOとWorld Bankの月次データを整形・統合
-
穀物と原油の時系列を重ね合わせ、価格の共動性を可視化
-
ピアソン相関係数(0.877)により、両市場の強い正の関係を定量化
この結果は、**「エネルギー価格が食料価格を先導する構造」**を裏付けるものであり、
統計や経済分析の現場で応用できる再現性の高い分析手順を示しています。
もし今後さらに発展させたい場合は、以下のような分析もおすすめです:
-
ラグ相関分析:原油高から穀物高までの時間差を定量化
-
回帰モデル構築:原油価格を説明変数とする予測式の作成
-
可視化強化:Plotlyなどでインタラクティブに比較
このコードは「実務でも使える再現性重視の分析テンプレート」です。
データ分析を学びたい方や、世界インフレ構造をPythonで理解したい方の実践ガイドとして活用してください。
本記事で扱った分析は、すべてPythonで再現できます。
自分の手を動かして分析をしてみたい方は、
👉テックアカデミーのデータサイエンスコースがおすすめです。
コメント