审计不平等观测及其年份
保留缺失年份,比较带年份的 Gini 观测,不制造同步排名。
目标与运行方法
本课适合具备 Python 基础的本科生。先阅读每一步的方法与图注,再修改参数。AI 练习为可选部分,不需要 AI 账号即可完成核心课程。数据写在 notebook metadata 中,不需要另下载数据文件。请保持 notebook 已保存到当前工作文件夹。
学习任务是理解本课的研究问题、执行透明的计算、校验结果,并说明结论的边界。
环境与参数
from pathlib import Path
import base64, gzip, hashlib, json, platform
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display, HTML
from IPython.display import display as _display
def display(value):
if isinstance(value,pd.DataFrame):
table=value.to_html(max_rows=12,escape=True)
style="<style>.vibeit-readable-table{max-width:100%;overflow-x:auto}.vibeit-readable-table table{width:max-content;max-width:none;border-collapse:collapse}.vibeit-readable-table td,.vibeit-readable-table th{white-space:nowrap!important;word-break:normal!important;overflow-wrap:normal!important}</style>"
return _display(HTML(style+'<div class="vibeit-readable-table">'+table+'</div>'))
return _display(value)
RECIPE_ID='ec03-inequality'
OUTPUT_DIR=Path.cwd()/"results"/RECIPE_ID
plt.rcParams.update({"figure.dpi":120,"font.size":10,"axes.spines.top":False,"axes.spines.right":False,
"axes.prop_cycle":plt.cycler(color=["#18785f","#416aa6","#bc6541","#9974a5"])})
print("Python:",platform.python_version(),"; NumPy:",np.__version__,"; Pandas:",pd.__version__)
print("Working folder:",Path.cwd())
print("Core data mode: embedded snapshot; no network requests")
Python: 3.13.13 ; NumPy: 2.5.3 ; Pandas: 3.0.6 Working folder: /Users/zhiluo/Developer/vibeit-cookbook/cookbook/downloads Core data mode: embedded snapshot; no network requests
读取内嵌快照
def load_snapshot(recipe_id, expected_sha256, snapshot_key):
"""Read embedded data from this notebook, including a renamed copy."""
for path in sorted(Path.cwd().glob("*.ipynb")):
try:
notebook = json.loads(path.read_text(encoding="utf-8"))
metadata = notebook.get("metadata", {}).get("vibeit_cookbook", {})
blob = metadata.get("snapshots", {}).get(snapshot_key)
if metadata.get("recipe_id") != recipe_id or not blob:
continue
if blob.get("sha256") != expected_sha256:
continue
raw = gzip.decompress(base64.b64decode(blob["gzip_base64"], validate=True))
if hashlib.sha256(raw).hexdigest() != expected_sha256:
raise ValueError("Embedded snapshot checksum mismatch: " + snapshot_key)
return json.loads(raw)
except (OSError, json.JSONDecodeError):
continue
raise FileNotFoundError(
"Save/open the complete .ipynb in the active working folder. "
"The embedded snapshot could not be located for " + recipe_id)
SNAPSHOT_HASHES={'worldbank': 'd45779250297fb9371748b85b81321b2ae88f93ecf70cfb88256647a68e54376'}
def snapshot(key):
return load_snapshot(RECIPE_ID,SNAPSHOT_HASHES[key],key)
print("Embedded snapshots:",list(SNAPSHOT_HASHES))
Embedded snapshots: ['worldbank']
方法函数
def worldbank_panel(payload):
"""Preserve missing observations; official economy metadata excludes aggregates."""
economies=pd.DataFrame(payload['economies']).set_index('iso3')
observations=pd.DataFrame(payload['observations'])
observations=observations[observations.iso3.isin(economies.index)].copy()
if observations.duplicated(['iso3','year','indicator']).any():raise ValueError('Duplicate economy/year/indicator observations')
observations['value']=pd.to_numeric(observations.value,errors='raise')
wide=observations.pivot(index=['iso3','year'],columns='indicator',values='value').sort_index()
return wide,economies,observations
print("Method ready: worldbank_panel")
Method ready: worldbank_panel
数据与模型边界
World Bank 记录保留定义、缺失观测及参考年。六个经济体为声明例子,不是全球随机样本。国家均值、价格篮子换算和 Gini 指数描述不同量,调查概念及覆盖可能不同。
分步分析
1. 保留观测年份
SI.POV.GINI 为 0–100 指数。指标参考年、收入/消费概念及覆盖人群可能不同,缺失观测保持缺失。
wb=snapshot("worldbank");panel,economies,observations=worldbank_panel(wb)
countries=["CHN","USA","DEU","BRA","IND","ZAF"]
assert set(countries)<=set(economies.index)
print("Economy/year records:",len(panel),"; official aggregates excluded; missing values preserved")
display(economies.loc[countries,["name","region","income_group"]])
gini=panel["SI.POV.GINI"].unstack("iso3").reindex(index=range(2010,2025),columns=countries)
observed=gini.stack().dropna().rename("Gini_index").reset_index()
assert observed.Gini_index.between(0,100).all();display(observed.head(8))
Economy/year records: 3255 ; official aggregates excluded; missing values preserved
| name | region | income_group | |
|---|---|---|---|
| iso3 | |||
| CHN | China | East Asia & Pacific | Upper middle income |
| USA | United States | North America | High income |
| DEU | Germany | Europe & Central Asia | High income |
| BRA | Brazil | Latin America & Caribbean | Upper middle income |
| IND | India | South Asia | Lower middle income |
| ZAF | South Africa | Sub-Saharan Africa | Upper middle income |
| year | iso3 | Gini_index | |
|---|---|---|---|
| 0 | 2010 | CHN | 43.7 |
| 1 | 2010 | USA | 40.2 |
| 2 | 2010 | DEU | 30.2 |
| 3 | 2010 | ZAF | 60.9 |
| 4 | 2011 | CHN | 42.3 |
| 5 | 2011 | USA | 41.2 |
| 6 | 2011 | DEU | 30.4 |
| 7 | 2011 | BRA | 52.9 |
2. 展示实际报告值
标记代表观测。缺失年不是零或不变不平等,避免暗示插值的连线。
fig,ax=plt.subplots(figsize=(9,5))
for code in countries:ax.plot(gini.index,gini[code],"o",label=economies.loc[code,"name"])
ax.set(xlabel="Indicator-reference year",ylabel="Gini index (0–100)",title="Reported values without imputation");ax.legend(fontsize=8);plt.tight_layout();plt.show()
3. 为最近可得值标日期
固定经济体顺序与年份展示可得性。不同年份不是同步全球排名,无观测者保持空。
latest=observed.sort_values("year").groupby("iso3").tail(1).set_index("iso3").reindex(countries)
display(latest)
labels=[economies.loc[c,"name"]+" ("+(str(int(latest.loc[c,"year"])) if pd.notna(latest.loc[c,"year"]) else "no observation")+")" for c in countries]
fig,ax=plt.subplots(figsize=(9,4));ax.barh(labels,latest.Gini_index)
ax.set(xlabel="Reported Gini index (0–100)",title="Last available 2010–2024 values; dates differ");plt.tight_layout();plt.show()
| year | Gini_index | |
|---|---|---|
| iso3 | ||
| CHN | 2022 | 36.0 |
| USA | 2024 | 41.8 |
| DEU | 2022 | 33.7 |
| BRA | 2024 | 50.3 |
| IND | 2023 | 23.0 |
| ZAF | 2022 | 54.1 |
4. 审计可得性矩阵
二值颜色表示是否有来源观测,不猜缺失值。同年和最近值选择回答不同问题。
fig,ax=plt.subplots(figsize=(9,4));im=ax.imshow(gini.notna().T,aspect="auto",cmap="Blues",vmin=0,vmax=1)
ax.set_xticks(range(15),range(2010,2025),rotation=45);ax.set_yticks(range(6),[economies.loc[c,"name"] for c in countries])
ax.set(xlabel="Indicator year",title="Coverage: 1=reported, 0=missing");fig.colorbar(im,ax=ax,ticks=[0,1]);plt.tight_layout();plt.show()
5. 核对日期并导出完整覆盖
直接计数有效格,并按来源可得性核对选择年。明确空选择,不人为同步年份。
assert len(observed)==int(gini.notna().to_numpy().sum())
for code in countries:
available=gini[code].dropna()
if not available.empty:assert latest.loc[code,"year"]==available.index.max()
OUTPUT_DIR.mkdir(parents=True,exist_ok=True);gini.to_csv(OUTPUT_DIR/"Gini-with-missing-years.csv")
latest.to_csv(OUTPUT_DIR/"dated-last-observations.csv")
print("Source count/year selection reconciled:",len(observed),"observations")
Source count/year selection reconciled: 61 observations
自主练习与参考答案
- 为何显示各最近值年份?
- 单个 Gini 能否重建完整分布?
参考解释。 年份/概念不同;单个 Gini 不能唯一确定 Lorenz 曲线或分布。
先保留当前 notebook 副本,再修改参数。把新图与原图一起比较,并记录改变了哪些输入、哪些计算和哪些结论。
可选的 AI 编程练习
提示词 1
仅用 NumPy、Pandas、Matplotlib 限定共同有效年并报告排除。
提示词 2
同包统计有效/缺失年,不填补。
人工验收。 保留原参考年和 0–100 单位,明确空选择。
检查修改后的源代码,再手动运行受影响单元及后续校验。要求助手解释修改的目的、使用的包和数据来源,并用实际输出核对解释。
可选联网扩展
RUN_ONLINE_UPDATE=False
if RUN_ONLINE_UPDATE:
import requests
try:
response=requests.get('https://api.worldbank.org/v2/indicator/NY.GDP.PCAP.KD?format=json',timeout=20)
response.raise_for_status()
print("Source:",response.url)
print(response.text[:700])
except requests.RequestException as error:
print("Online extension unavailable:",type(error).__name__,str(error)[:160])
else:
print("Online extension skipped; embedded core data unchanged")
Online extension skipped; embedded core data unchanged
来源、快照与下一步
World Bank economy metadata — World Bank CC BY 4.0 with additional terms; retain original indicator attribution; retrieved 2026-10-09. SHA-256
c9acf3932785191a649cbc04c3056af4cf64a236e5c3b49d49be25ddb0440bce. Preserve economy IDs, region and income-group metadata; exclude aggregates in student analyses.World Bank NY.GDP.PCAP.KD — World Bank CC BY 4.0 with additional terms; original sources retained in indicator metadata; retrieved 2026-10-09. SHA-256
59a9efaf20ab359c7832f24da45dda2282511c0eaf927d044583f47d08e02cda. Retain official observations including null values and footnotes, 2010–2024; no interpolation; no aggregate-country mixing.World Bank indicator metadata NY.GDP.PCAP.KD — World Bank CC BY 4.0 with additional terms; retrieved 2026-10-09. SHA-256
46689488cd435920647264ede1bfb2d4b51b09800fb36f3d3b1422a0b11ea49d. Preserve indicator definition, source organization and source note.World Bank NY.GDP.MKTP.KD — World Bank CC BY 4.0 with additional terms; original sources retained in indicator metadata; retrieved 2026-10-09. SHA-256
466f4e3176b509613f3df99acffce89b5f1ea14472c376dd10d8b8f67f6172b0. Retain official observations including null values and footnotes, 2010–2024; no interpolation; no aggregate-country mixing.World Bank indicator metadata NY.GDP.MKTP.KD — World Bank CC BY 4.0 with additional terms; retrieved 2026-10-09. SHA-256
bc4bc0ffec1755410f52b1091c6b1f46917c7417977102350d3d1102b4659216. Preserve indicator definition, source organization and source note.World Bank SP.POP.TOTL — World Bank CC BY 4.0 with additional terms; original sources retained in indicator metadata; retrieved 2026-10-09. SHA-256
7ecf8d749dbddd87a269f2019e6d42ed32875c57565cf5c5af097c6e6c9af528. Retain official observations including null values and footnotes, 2010–2024; no interpolation; no aggregate-country mixing.World Bank indicator metadata SP.POP.TOTL — World Bank CC BY 4.0 with additional terms; retrieved 2026-10-09. SHA-256
2f8491efc00bf2c0995112ff8e87aba69e5e9d22d0880b22f7e3a4ec757ba05c. Preserve indicator definition, source organization and source note.World Bank SP.DYN.LE00.IN — World Bank CC BY 4.0 with additional terms; original sources retained in indicator metadata; retrieved 2026-10-09. SHA-256
d8b5c6bd7fecaf8cee0e422444719ba1f42ec70996308bc74afd14ee48799055. Retain official observations including null values and footnotes, 2010–2024; no interpolation; no aggregate-country mixing.World Bank indicator metadata SP.DYN.LE00.IN — World Bank CC BY 4.0 with additional terms; retrieved 2026-10-09. SHA-256
a39cb6fddfbbb953053690366243dffe77a266c4deae79c46ce5a06da9f5fc31. Preserve indicator definition, source organization and source note.World Bank FP.CPI.TOTL — World Bank CC BY 4.0 with additional terms; original sources retained in indicator metadata; retrieved 2026-10-09. SHA-256
55c3b71ad4dd8c92c15fa7dc2b502a3d60f26cf47ae9a24e384bc2ff6108ff56. Retain official observations including null values and footnotes, 2010–2024; no interpolation; no aggregate-country mixing.World Bank indicator metadata FP.CPI.TOTL — World Bank CC BY 4.0 with additional terms; retrieved 2026-10-09. SHA-256
13b1e3c4b2b72f7fb3a630b4dde37f0e68e6d5e78dc06b2437dfea0c0b93af46. Preserve indicator definition, source organization and source note.World Bank FP.CPI.TOTL.ZG — World Bank CC BY 4.0 with additional terms; original sources retained in indicator metadata; retrieved 2026-10-09. SHA-256
849b6a88a84a7efdeb92d89e8db1db36f86543e28ff8eb645e0feaa8c634def7. Retain official observations including null values and footnotes, 2010–2024; no interpolation; no aggregate-country mixing.World Bank indicator metadata FP.CPI.TOTL.ZG — World Bank CC BY 4.0 with additional terms; retrieved 2026-10-09. SHA-256
df9371a3b6c01e55a3f28991e62e1b1ebbe0cd2a7da94456be9938c7a2962233. Preserve indicator definition, source organization and source note.World Bank SI.POV.GINI — World Bank CC BY 4.0 with additional terms; original sources retained in indicator metadata; retrieved 2026-10-09. SHA-256
4919413d3b9ef06b7445c3fd42d47b8a09e9836bbab7be84e4993099ffdc7ab2. Retain official observations including null values and footnotes, 2010–2024; no interpolation; no aggregate-country mixing.World Bank indicator metadata SI.POV.GINI — World Bank CC BY 4.0 with additional terms; retrieved 2026-10-09. SHA-256
e377bf82b38024748153880ff90c0106a0ef0fd8cb04761146cc60a2609cab3d. Preserve indicator definition, source organization and source note.
下一步。 在保留本课的数据检查、参数记录和结果校验之后,将相同方法用于自己的公开或已获授权数据。记录研究设计与方法限制,不把示例结果当成新实验的验证。完整数据许可与生成说明见 cookbook 网页。