2. 申请评分卡数据字典构建
任务说明
本案例基于一份原始字段说明(字段名、中文含义、原始类型、取值/备注),生成标准化数据字典:统一字段类型(数值型/类别型/文本型/日期型)、规范字段命名、补充取值说明,并输出为 CSV 与 Markdown 两种可直接交付的形式。输入数据在本案例中直接内置,无需外部文件即可运行。
实现代码
import csv
import re
from pathlib import Path
# 原始字段说明:字段名, 中文含义, 原始类型, 取值/备注
RAW_FIELDS = [
("cust_id", "客户编号", "string", "唯一标识,如 C000123"),
("apply_date", "申请日期", "string", "格式 YYYY-MM-DD"),
("age", "年龄", "int", "18-70"),
("gender", "性别", "string", "M=男, F=女"),
("marital", "婚姻状况", "string", "S=未婚, M=已婚, D=离异"),
("education", "学历", "string", "1=高中及以下,2=大专,3=本科,4=硕士及以上"),
("monthly_inc", "月收入(元)", "float", ">=0"),
("loan_amt", "申请金额(元)","float", ">0"),
("loan_term", "贷款期限(月)","int", "6/12/24/36"),
("has_house", "是否有房", "string", "Y/N"),
("overdue_cnt", "近2年逾期次数","int", ">=0"),
("apply_result", "审批结果", "string", "1=通过, 0=拒绝"),
]
# 原始类型 -> 标准类型
TYPE_MAP = {
"int": "数值型", "float": "数值型",
"string": "文本型", "date": "日期型",
}
# 字段名 -> 标准类型覆盖(string 但语义为类别/日期)
SEMANTIC_OVERRIDE = {
"cust_id": "文本型",
"apply_date": "日期型",
"gender": "类别型",
"marital": "类别型",
"education": "类别型",
"has_house": "类别型",
"apply_result": "类别型",
}
def normalize_name(name: str) -> str:
"""字段名统一为小写下划线风格。"""
return re.sub(r"[^a-z0-9]+", "_", name.strip().lower()).strip("_")
def build_dictionary(raw_fields):
rows = []
for name, meaning, raw_type, note in raw_fields:
std_name = normalize_name(name)
std_type = SEMANTIC_OVERRIDE.get(std_name, TYPE_MAP.get(raw_type, "文本型"))
rows.append({
"字段名": std_name,
"中文含义": meaning,
"字段类型": std_type,
"取值说明": note,
})
return rows
def write_csv(rows, path: Path):
with path.open("w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=["字段名", "中文含义", "字段类型", "取值说明"])
writer.writeheader()
writer.writerows(rows)
def write_markdown(rows, path: Path):
header = "| 字段名 | 中文含义 | 字段类型 | 取值说明 |\n|---|---|---|---|\n"
body = "".join(
f"| {r['字段名']} | {r['中文含义']} | {r['字段类型']} | {r['取值说明']} |\n"
for r in rows
)
path.write_text(header + body, encoding="utf-8")
if __name__ == "__main__":
out_dir = Path("output")
out_dir.mkdir(exist_ok=True)
dict_rows = build_dictionary(RAW_FIELDS)
write_csv(dict_rows, out_dir / "data_dictionary.csv")
write_markdown(dict_rows, out_dir / "data_dictionary.md")
# 控制台打印,便于快速核对
for r in dict_rows:
print(f"{r['字段名']:<14}{r['字段类型']:<6}{r['中文含义']}")
print(f"\n共 {len(dict_rows)} 个字段,已输出到 {out_dir}/")
运行方式
python build_dict.py
脚本会在当前目录创建 output/,生成 data_dictionary.csv 与 data_dictionary.md。
验证方法与通过条件
- 控制台按“字段名 / 字段类型 / 中文含义”逐行打印 12 个字段,字段名均为小写下划线风格。
output/data_dictionary.csv表头为字段名,中文含义,字段类型,取值说明,共 12 行数据。- 类型判定符合语义:
age/loan_amt/overdue_cnt等为“数值型”,gender/marital/education/has_house/apply_result为“类别型”,apply_date为“日期型”,cust_id为“文本型”。 - Markdown 文件可直接粘贴到文档中渲染为表格,列与 CSV 一致。
常见问题
- 若原始字段说明来自 Excel,可先用
pandas.read_excel读入并转成RAW_FIELDS同样的四元组列表,其余逻辑不变。 - 新增字段时只需在
RAW_FIELDS追加一行;若其string类型实际为类别或日期,在SEMANTIC_OVERRIDE中登记即可。