社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

手把手教你学python进阶版第四课:Python模板式自动化Word报告:以沪深交易所现券交易月报分析为例

与尔岩说 • 1 年前 • 233 次点击  

手把手教你学python基础课系列快速回顾

1、“零基础包学会” 手把手教你学python一:如何快速找到学习资源?

2、手把手教你学python第二课:如何迅速上手马上能run

3、手把手教你学python第三课:数据分析,学会使用pandas大杀器

4、手把手教你学python第四课:数据可视化

5、手把手教你学python第五课:各种渠道获取数据,快速学会windpy和网络爬虫

6、手把手教你学python第六课:技术分析入门-talib

手把手教你学python第六课:技术分析入门-talib-成交量及曲线形态

手把手教你学python第六课:技术分析入门-talib-安装及动量指标

7、手把手教你学python第七课:数据分析和机器学习


手把手教你学python进阶系列快速回顾

1、手把手教你学python进阶版:整体框架

2、手把手教你学python进阶版第一课:Python常用文件目录操作—以清理PC微信缓存文件为例

3、手把手教你学python进阶版第二课:Python网络数据抓取—以沪深交易所现券交易月报为例

4、手把手教你学python进阶版第三课:Python数据分析与绘图:以沪深交易所现券交易月报为例

2023

手把手教你学python系列进阶版

写在最初


在新的一年与尔岩说将继续之前的手把手教你学python专栏(停更的原因一部分是因为大家说之前的需要时间消化,所以停了一段时间,另一部分原因是想邀请比我更专业而且实用性更强的王者们来上进阶课程),主笔加入了我的两个非常好的两个朋友(笔名十月和木矛木心),下面是十月写在最初的话:


在塔勒布的《非对称风险》开篇章节中提到一句希腊谚语“Pathemata mathemata”,意即只有在痛苦的实践中才能学到东西

从经济学专业背景逐步走向需要大量编程经验的量化方向,我对此谚语深有体会,虽然目前已转向固收投研,编程技能仍在日常工作中发挥着重要的作用。

作为非专业“码农”,收到与尔岩说的邀请,初时颇觉惶恐,后又逐渐释然。总结和分享这些年踩过许多坑得到的经验教训,既是抛砖引玉,也是学习的一种方式。

Python作为一种胶水语言,随着AI技术的火热被越来越多人知道,科学计算相关领域的工具包也非常全面。这里会先把我日常投研中经常用到的工具包简单总括介绍,主要涉及通用模块、科学计算、高性能编程、数据库交互、绘图、OFFICE协作、爬虫等七大类别,后续将结合具体案例再逐渐展开不同工具包的用法。


这里会定期更新一些实际案例和具体用法,如果你和我一样热爱用科技提高工作效率,并想要一起研究一些有意思的事情,欢迎一起来进阶!!


Python数据展示操作


数据处理和展示操作是在日常高频使用的代码,且可复用性很强。(蓬蓬说:这部分用好了事半功倍,好的展示能力和挖掘能力是非常重要的,十月还是用了日常中需求很多的例子来教学的,亲自尝试一定有收获!!)


在前一个案例中,我们基于沪深交易所现券交易月报的历史数据,简要展示了Python数据分析与绘图的一些常用方法;本次案例将基于输出的分析数据和图表,展示如何利用Word模板生成自动化分析报告;主要难点在于需要掌握Jinja2的部分语法,用于制作Word模板,涉及基础文本、富文本、图片和表格。

首先,我们在VSCode中新建一个jupyter notebook,与前一个案例保持在同一文件夹下。然后导入本案例中需要用到的核心模块。本案例中将使用docxtpl,可通过"pip install kaleido"进行安装。
#  导入数据分析需要使用的Python模块import pandas as pdimport datetimeimport os 
# 导入模版式自动化Word报告所需模块# 底层为 Python-Docx 和 jinja2# DocxTemplate 用于模板的读取和渲染# RichText 用于富文本的渲染# InlineImage 用于图片的读取和渲染# https://docxtpl.readthedocs.io/en/latest/from docxtpl import DocxTemplate, RichText, InlineImage
# 导入单位转换函数,用于控制图表尺寸from docx.shared import Mm
与前一案例类似,我们先设置好用于保存案例输出数据、图表和分析报告的文件目录。在前一案例的基础上,本次需要新建Report文件夹,用于保存Word模板和输出报告。
#  新建Notebook,与案例三保持在同一文件夹PATH_BASE = os.path.abspath("./")PATH_DATA = os.path.join(PATH_BASE, "Data")PATH_PLOT = os.path.join(PATH_BASE, "Plot")PATH_REPORT = os.path.join(PATH_BASE, "Report")
# 利用os模块,在Notebook的相同目录下新建Report文件夹,用于存放图片# 判断Report文件夹是否存在,若不存在则创建if not os.path.exists(PATH_REPORT): os.mkdir(PATH_REPORT)


Word模板核心语法

基础文本


通过在模板中创建由双大括号括起来的变量名,并在模板渲染时,将所需文本以字符串形式赋值给该变量,即可完成基础文本的填充;注意变量名前后均需留出一个空格。


#  在模板渲染时,通过字典将字符串赋值给指定的基础文本变量{    "变量名_基础文本": "基础文本内容",}



富文本
通过在模板中创建由双大括号括起来的变量名,并在模板渲染时,将所需文本以RichText形式赋值给该变量,即可完成富文本的填充;注意变量名前后均需留出一个空格。
#  在模板渲染时,通过字典将 RichText 赋值给指定的富文本变量, 包含多个可调整参数{    "变量名_富文本": RichText(        text = "富文本内容",                style = None,  # 文本样式        color = None,  # 文本颜色,十六进制格式        highlight = None,  # 文本高亮,高亮颜色为十六进制格式        size = None,  # 字体大小        subscript = False,  # 是否下标        superscript = False,  # 是否上标        bold = False,  # 是否加粗        italic = False,  # 是否斜体        underline = False,  # 是否有下划线        strike = False,  # 是否有删除线        font = None,  # 字体名称        url_id = None,  # 超链接id,由 DocxTemplate.build_url_id("链接地址") 生成


    
        ),}


图片
通过在模板中创建由双大括号括起来的变量名,并在模板渲染时,将所需图片以InlineImage形式赋值给该变量,即可完成图片的填充;注意变量名前后均需留出一个空格。
#  在模板渲染时,通过字典将 InlineImage 赋值给指定的富文本变量, 包含多个可调整参数{    "变量名_图片": InlineImage(        tpl = None,  # DocxTemplate 模板对象        image_descriptor = "图片路径",  # 图片文件路径        width = None,  # 图片宽度, 可结合 Mm 按毫米指定        height = None,  # 图片高度, 可结合 Mm 按毫米指定        ),}


表格
表格模板的创建相对复杂,需要用到循环语法,以实现行列数据的分别填充。下图为简要示例,其中表头变量为des_table_cols,表数据为des_table_contents;通常表头变量和表数据变量均通过列表形式赋值。
#  按列填充数据的基本语法格式{%tc for col in cols %} {{ col }} {%tc endfor %}
# 按行填充数据的基本语法格式{%tr for item in items %}{%tc for col in item %} {{ col }} {%tc endfor %}{%tr endfor %}


#  在模板渲染时,通过字典将表头列表和表数据列表分别赋值给指定的变量, 以上图为例,赋值格式示例如下{    "des_table_cols": ["C1", "C2", "C3"],    "des_table_contents": [        {"lable": "R1", "cols": [1, 2, 3]},        {"lable": "R2", "cols": [4, 5, 6]},        {"lable": "R3", "cols": [7, 8, 9]},    ],}


注释
为提高Word模板的可读性,可利用Jinja2的注释语法,在模板中添加注释文本,这些注释不会参与到模板的渲染中。
{# 注释文本 #}


示例:沪深交易所现券交易月报分析

Word模板制作
参考上述模板语法,我们在Report目录下新建一个Docx格式的Word文档,并命名为“模板-沪深交易所现券交易月报分析示例.docx”。如下图所示,在文档中简单编辑一个Word模板,包括不同投资者类别转债历史成交金额的描述性统计和相关性分析两个表格,以及四张图片,包括:代表性投资者转债成交金额历史变化情况(折线图)、不同投资者类别转债历史成交金额分布特征(箱型图)、不同投资者类别转债近期成交金额对比(柱状图)和不同投资者类别转债历史成交金额相关性矩阵(散点图)。


Word模板渲染


对照上述模板中需要赋值的变量,我们在notebook中读取所需的描述性统计和相关性分析数据;然后选择合适的变量类型和数据格式,编辑渲染Word模板所需的字典;最后将内容渲染到Word模板中,即可保存为初步的分析报告,以供进一步的细化编辑和修改。
#  根据前一案例中输出的分析数据和编码格式,分别读取描述性统计和相关性分析数据data_cb_describe = pd.read_csv(    os.path.join(PATH_DATA, "data_cb_describe.csv"),     encoding="GB18030",    index_col=[0])
data_cb_corr = pd.read_csv( os.path.join(PATH_DATA, "data_cb_corr.csv"), encoding="GB18030", index_col=[0])
# 利用 DocxTemplate 导入编辑完成的Word模板report_tpl = DocxTemplate( template_file = os.path.join(PATH_REPORT, "模板-沪深交易所现券交易月报分析示例.docx"))
# 利用字典编辑需要渲染到Word模板中的内容context = { # 分析报告日期,渲染为富文本,设置字体颜色为红色 'analysis_date': RichText( text = datetime.date.today().strftime("%Y-%m-%d"), color = "FF6666", ), # 分析报告描述内容,渲染为基础文本 "summary": "模板式自动化Word报告示例", # 描述性统计表格,分别对表头和表数据赋值 # 表数据的格式调整可结合 pandas.DataFrame.agg 和 lambda函数 实现 # 此处 count 数据不保留小数,其他数据保留2位小数 'des_table_cols': data_cb_describe.columns.to_list(), 'des_table_contents': data_cb_describe.agg( lambda x: {'label': x.name, 'cols': [f"{d:.0f}" if x.name == "count" else f"{d:.2f}" for d in x]}, axis=1 ).to_list(), # 相关性分析表格,分别对表头和表数据赋值 # 表数据的格式调整可结合 pandas.DataFrame.agg 和 lambda函数 实现 # 此处数据均保留2位小数 'corr_table_cols': data_cb_corr.columns.to_list(), 'corr_table_contents': data_cb_corr.agg( lambda x: {'label': x.name, 'cols': [f"{d:.2f}" for d in x]}, axis=1 ).to_list(), # 成交金额历史变化情况(折线图),渲染为图片 'fig_line': InlineImage( tpl = report_tpl, image_descriptor = os.path.join(PATH_PLOT, "折线图.png"), width = Mm(150), ), # 成交金额分布特征(箱型图),渲染为图片 'fig_box': InlineImage( tpl = report_tpl, image_descriptor = os.path.join(PATH_PLOT, "箱型图.png"), width = Mm(150) ), # 近期成交金额对比(柱状图),渲染为图片 'fig_bar': InlineImage( tpl = report_tpl, image_descriptor = os.path.join(PATH_PLOT, "柱状图.png"), width = Mm(150) ), # 成交金额相关性矩阵(散点图),渲染为图片 'fig_scatter': InlineImage( tpl = report_tpl, image_descriptor = os.path.join(PATH_PLOT, "散点图.png"), width = Mm(150) ),}
# 利用 DocxTemplate.render 渲染模板内容# 利用 DocxTemplate.save 保存渲染后的Word文档report_tpl.render(context = context)report_tpl.save(os.path.join(PATH_REPORT, "沪深交易所现券交易月报分析示例.docx"))

本次案例基于沪深交易所现券交易月报分析数据和图片,主要展示了Python数据分析中模板式自动化Word报告的常用方法,主要涉及部分Jinja2模板语法的使用,以及Word模板与Python之间的配合。若有错漏之处,还请各位批评指正。

——文 by 十月

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/153031
 
233 次点击