该系统基于Streamlit框架开发,整合多年度营业收入与营业利润数据,结合申万行业分类标准,实现行业增长趋势的动态可视化分析。
通过将复杂的财务数据处理流程模块化封装,为非技术用户提供直观的交互式分析工具,有效降低专业财务分析的技术门槛,显著提升跨行业数据比对与趋势研判的效率。
一、技术架构
前端框架:Streamlit(快速构建Web应用)
数据处理:Pandas(数据清洗、转换、聚合)
可视化:Matplotlib(图表绘制)
行业标准:申万行业分类
开发语言:Python
二、数据准备

1. Data2018-2024.elsx文件要包含的字段:

2. 股票基本信息表.xlsx文件包含字段:

3. 上市公司基本信息.xlsx文件字段:

4. 申万行业分类.xlsx文件字段:

三、核心功能模块详解
1. 多年度数据合并
-
文件识别:通过文件名模式匹配,自动识别各年度数据文件
-
字段提取:只读取核心财务指标,提升处理效率
-
时间标记:为每条记录添加年份标签,便于时间序列分析
import pandas as pd
import os
# 合并不同年份数据到excel表
path = "./"
data = []
# 遍历文件夹中的所有excel文件
dir = os.listdir(path) # os.listdir(path)——列出指定路径path下的所有文件/文件夹名称
for file_name in dir:
# 筛选以“Data”开头,“.xlsx”结尾的文件名
if file_name.startswith("Data") and file_name.endswith(".xlsx"):
# 构建完整路径
file_path = os.path.join(path, file_name)
# 读取Excel文件
df = pd.read_excel(file_path, usecols=["ts_code", "营业收入", "营业利润"]) # usecols——选择指定列
# 从文件名提取年份(从"Data2018.xlsx"中提取"2018")
year = file_name.replace("Data", "").replace(".xlsx", "") #去除前缀“.Data”、后缀“.xlsx”,只留下“2018”
df["年份"] = year # 新增“年份”列
data.append(df)
# 合并所有数据
merged_df = pd.concat(data, ignore_index=True) # ignore_index=True——重置索引,创建一个从0开始的新索引
2. 申万行业关联分析
申万行业分类是中国资本市场最权威的行业分类标准之一,利用 merger() 实现财务数据与行业分类的精准关联。
-
left_on和right_on指定关联键,确保精准匹配; -
how="left"保证即使某些公司无行业分类,财务数据也不会丢失。
# 加载申万行业分类标准
info = pd.read_excel('申万行业分类.xlsx',
usecols=["股票代码", "新版一级行业", "新版二级行业", "新版三级行业"])
# 双表关联:将财务数据映射到行业分类
merged_with_industry = pd.merge(
merged_df, # 财务数据表
info, # 行业分类表
left_on="ts_code", # 财务数据中的股票代码
right_on="股票代码", # 行业表中的股票代码
how="left" # 左连接,保留所有财务数据
)
3. 核心财务指标增长率计算
增长率分析是财务趋势分析的核心,利用groupby()、pct_change()进行分组滚动计算。
计算公式:
营业收入增长率 = (本年营业收入 - 上年营业收入) / 上年营业收入 × 100%
营业利润增长率 = (本年营业利润 - 上年营业利润) / 上年营业利润 × 100%
# 按行业和公司排序,为分组计算做准备
merged_with_industry = merged_with_industry.sort_values(
by=[level, "ts_code", "年份"]
)
# 计算营业收入同比增长率
merged_with_industry["营业收入增长率"] = (
merged_with_industry.groupby([level, "ts_code"])["营业收入"]
.pct_change() * 100
)
# 计算营业利润同比增长率
merged_with_industry["营业利润增长率"] = (
merged_with_industry.groupby([level, "ts_code"])["营业利润"]
.pct_change() * 100
)
# 处理缺失值(首年数据无增长率)
merged_with_industry[["营业收入增长率", "营业利润增长率"]] = (
merged_with_industry[["营业收入增长率", "营业利润增长率"]].fillna(0)
)
四、交互式可视化界面设计
1. 侧边栏控制面板
import streamlit as st
# 设置页面配置
st.set_page_config(
page_title="行业应收&利润可视化分析",
layout='wide', # 宽屏模式,充分利用屏幕空间
)
# 侧边栏控制面板
with st.sidebar:
st.subheader('📚 请选择申万行业级别')
# 三级行业分类选择器
level = st.selectbox(" ", ['新版一级行业','新版二级行业','新版三级行业'])
st.subheader('请选择分析类型')
# 财务指标选择器
cla = st.selectbox(" ", ['营业收入','营业利润'])
2. 行业数据汇总展示
聚合操作:.agg()函数对分组后的数据执行聚合计算,比如将每个行业每年的营业收入加总,并统计上市公司数量。它将每组内的多行数据浓缩为单行统计结果,实现从明细数据到汇总数据的转换。
# 根据用户选择动态聚合数据
if cla == "营业收入":
df_sum = merged_with_industry.groupby([level, "年份"]).agg(
营业收入=("营业收入", lambda x: x.astype(float).sum()),
上市公司数量=("ts_code", "nunique")
).reset_index()
else:
df_sum = merged_with_industry.groupby([level, "年份"]).agg(
营业利润=("营业利润", lambda x: x.astype(float).sum()),
上市公司数量=("ts_code", "nunique")
).reset_index()
# 计算行业级增长率
df_sum = df_sum.sort_values([level, "年份"])
growth_col = f"{cla}增长率"
df_sum[growth_col] = (df_sum[cla] - df_sum.groupby(level)[cla].shift(1)) / df_sum.groupby(level)[cla].shift(1) * 100
df_sum[growth_col] = df_sum[growth_col].fillna(0) # 处理首年数据
# 重命名列名
df_sum.rename(columns={level: "行业名称", "年份": "年度"}, inplace=True)
# 格式化显示
df_sum[f"{cla}增长率"] = df_sum[f"{cla}增长率"].apply(lambda x: f"{x:.2f}%")
# 在Streamlit中展示交互式表格
st.dataframe(df_sum, use_container_width=True, hide_index=True)
# use_container_width=True —— 表格自适应容器宽度
# hide_index=True —— 隐藏默认的索引列
3. Top8行业增长趋势可视化
通过多子图展示最近六年各行业增长情况。
import matplotlib.pyplot as plt
# 获取最近六年数据
years = sorted(merged_with_industry["年份"].astype(int).unique())[-6:]
# 设置中文字体
plt.rcParams['font.sans-serif'] = 'Simhei'
# 创建3行2列的子图布局
fig, axes = plt.subplots(3, 2, figsize=(20, 15))
axes = axes.flatten()
bar_color = "#1f77b4" # 统一的柱状图颜色
for i, year in enumerate(years):
# 筛选当年数据
year_data = merged_with_industry[merged_with_industry["年份"].astype(int) == year]
# 按行业计算平均增长率
if cla == "营业收入":
growth_data = year_data.groupby(level)["营业收入增长率"].mean().reset_index()
else:
growth_data = year_data.groupby(level)["营业利润增长率"].mean().reset_index()
# 获取增长率最高的8个行业
top8 = growth_data.nlargest(8, f"{cla}增长率").sort_values(by=f"{cla}增长率")
# 绘制水平柱状图
axes[i].bar(top8[level], top8[f"{cla}增长率"], color=bar_color)
axes[i].set_title(f"{year}年{cla}增长率Top8行业", fontsize=14)
axes[i].set_xlabel("行业", fontsize=12)
axes[i].set_ylabel(f"{cla}增长率(%)", fontsize=12)
axes[i].grid(axis='x', linestyle='--', alpha=0.6) # 添加网格线
plt.tight_layout() # 自动调整子图间距
st.pyplot(fig) # 在Streamlit中展示图表
五、Streamlit简单页面展示

Top8行业增长柱状图:

六、可扩展性
本系统具有良好的架构扩展性,可以轻松添加新的数据源和分析维度。通过模块化设计和配置化参数,未来能够快速集成更多财务指标、时间粒度和分析方法。
439

被折叠的 条评论
为什么被折叠?



