一、任务描述
杜邦分析体系将净资产收益率(ROE)拆解为销售净利率、总资产周转率与权益乘数三因子,揭示了企业盈利、运营与杠杆三种不同的价值创造路径。然而,传统教学往往止步于公式计算与静态比较,学生"会算"却"不会判"——面对批量纵向企业数据,难以快速识别其主导驱动模式的演变与潜在财务风险。
本代码旨在构建一套六级颗粒度的驱动特征判别模型:以财务风险预警为最高优先级,依次识别高盈利、准高盈利、高周转、准高周转及均衡型五种企业画像,实现从手工计算到智能分类的跃迁。
二、操作向导
【知识点1】pd.read_excel:从Excel文件读取结构化数据,pandas通过openpyxl或xlrd引擎解析.xlsx/.xls文件,将工作表转化为DataFrame二维表结构。若文件含多个工作表,可用sheet_name="表名" 指定。
import pandas as pdfilename = "300415伊之密历年财务指标.xlsx"df = pd.read_excel(filename)
【知识点2】指标值调整:统一量纲与口径,原始数据常带百分号(%)或单位差异,直接运算会导致数量级错误。需通过除法/加法进行量纲归一化。
财务场景:
• 销售净利率(%) ÷ 100 → 转化为小数,便于与ROE同口径比较
• 产权比率(%) ÷ 100 + 1 → 由"负债/所有者权益"推导权益乘数,公式:权益乘数 = 资产/权益 = (负债+权益)/权益 = 1 + 产权比率
• 总资产周转率(次) → 单位为"次/年",无需转换
注意:调整前务必核对原始数据的单位标识,防止"小数点错位"。
npm = df['销售净利率(%)'] / 100 # 销售净利率(Net Profit Margin)tat = df['总资产周转率(次)'] # 总资产周转率(Total Asset Turnover)em = df['产权比率(%)'] / 100 + 1 # 权益乘数(Equity Multiplier)ROE = df['净资产收益率(%)'] / 100 # 净资产收益率date = df['日期'] # 时间序列索引
【知识点3】建立数据容器:空列表的初始化。列表(list)是Python内置的可变序列类型,支持动态扩容。在循环遍历前预先创建空列表,用于逐条存储分类结果。
财务场景:杜邦分析需对每一期财务数据打标签(如"高盈利驱动型"),由于数据行数随年报期数变化,使用列表可灵活适配不同长度。列表的append机制更适合"边遍历、边收集"的场景。
features = []# 建立"风险预警优先 + 主驱动识别 + 复合标签"识别模型for i in range(len(npm)): n, t, e = npm.iloc[i], tat.iloc[i], em.iloc[i] tags = []
【知识点4】list.append():向列表尾部追加元素,append()是列表的原地修改方法,将单个对象作为整体追加到列表末尾。
财务场景:在杜邦三因子分析中,一家企业可能同时具有多种驱动特征(如既"高盈利"又"高周转")。通过append向tags列表逐条添加特征标签,实现"非互斥、可叠加"的多维度画像。
# 第一层:风险预警(独立判断,不互斥)if e > 2.5 and n <= 0.05: tags.append("高杠杆风险")elif e > 2.5: tags.append("高杠杆")# 第二层:主驱动识别(允许叠加)if n > 0.10: tags.append("高盈利")elif n > 0.06: tags.append("盈利高")if t > 1.0: tags.append("高周转")elif t > 0.6: tags.append("周转快")
【知识点5】str.join():字符串拼接与标签合成,join()是字符串方法,以调用者(如"+")为分隔符,将可迭代对象(如列表)中的字符串元素连接成新字符串。
财务场景:当tags列表含多个特征(如["高盈利","高周转"])时,用"+".join(tags)合成"高盈利+高周转"的复合标签,既保留多维度信息,又便于Excel单元格展示。
语法:"分隔符".join(可迭代对象)
示例:"-".join(["A","B"]) → "A-B"
# 第三层:综合判定if not tags: if e > 2.0: features.append("杠杆依赖型") else: features.append("均衡型")else: features.append("+".join(tags))df['驱动特征'] = features
【知识点6】用字典构建DataFrame:列式数据组装。
财务场景:财务分析结果往往需要从原始DataFrame中抽取部分列,并与新生成的指标(如驱动特征)重新组合,形成分析报告。
字典结构天然对应"指标名:数据列"的映射关系,可读性强。字典各value的长度必须一致,否则报错。
df2 = pd.DataFrame({'日期': date,'净资产收益率': ROE,'销售净利率': npm,'总资产周转率': tat,'权益乘数': em,'驱动特征': features})print(df2)
【知识点7】pd.ExcelWriter:追加写入与sheet替换,ExcelWriter是pandas的上下文管理器,封装了Excel引擎(此处为openpyxl),支持"追加模式(a)"向已有文件写入。
if_sheet_exists="replace"表示若目标工作表已存在,则覆盖。
财务场景:财务分析常需"原始数据+分析结果"同文件存储,避免生成多个分散文件。追加模式可在不破坏原始数据的前提下,将"ROE驱动分析"结果写入新工作表,实现"数出一源、分级呈现"。
参数详解:
• engine="openpyxl":mode="a"仅支持openpyxl引擎
• mode="a":append追加;文件不存在时会报错,需预先创建
• if_sheet_exists="replace":同名表覆盖;
注意:使用with语句确保文件句柄自动关闭,防止文件占用锁定。
with pd.ExcelWriter(filename, engine="openpyxl", mode="a", if_sheet_exists="replace") as writer: df2.to_excel(writer, sheet_name="ROE 驱动分析", index=False)
教学转化:将此模型嵌入《财务管理实务》课程,学生可导入上市公司年报数据(如伊之密、海天味业),一键生成企业的驱动特征分布图。更详细内容请参阅钭志斌主编的《财务大数据分析(基于python)》。