自动根据数据生成降雨量实况Word报告

2023-10-25 03:59

本文主要是介绍自动根据数据生成降雨量实况Word报告,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:小小明

最近遇到一个有点烧脑的需求,其实也不算烧脑,主要是判断条件过多,对于我这种记忆力差,内存小的人来说容易出现内存溢出导致大脑宕机。也可能是因为我还没有找到能减小大脑内存压力的写法。
若读者有啥更好解决方案,欢迎评论噢!

先看看需求吧:

image-20210103105704976

主要就是要根据左侧的表格自动生成右侧的word统计报告,实际的各种可能性情况远比图中展示的要更加复杂。

好了,直接开始干代码吧:

数据读取

import pandas as pddf = pd.read_csv("11月份数据.csv", encoding='gbk')
# 当前统计月份
month = 11
df = df.query('月份==@month')
df

数据:

区域月份降雨量(mm)降雨距平(mm)观测站
06e63e112.9-0.70A站
11b8dd111.0-3.40A站
27c6a0112.3-3.04A站
3548ad118.50.10A站
41bafe118.72.20A站
551a451116.07.41A站
653f42116.81.10A站
74f644111.8-0.60A站
860a75110.0-2.60A站
94319d111.4-2.20A站
1062464112.2-1.00A站
1165cb4112.0-1.00A站
12e68da111.2-1.40A站
134156e113.1-0.40A站
141cc6d113.3-2.00A站
1516d40110.0-0.50B站
1654ac3113.20.00B站
17592ac114.1-0.20B站
1832046115.31.10B站
194e6f0111.20.50B站
203722c113.51.40C站
215379c111.3-2.90C站
2251eed113.2-0.60C站
232d91d112.80.90D站
2478896115.11.60D站
2525464115.51.50D站
2666955110.3-3.10D站
277639e110.0-1.10D站
281c5ff110.6-0.90D站
29ec4561112.2NaNE站
3029b6b117.34.00E站
31220de1112.29.10E站
323b5f01113.67.25E站

异常数据过滤

查看缺失值数量:

pd.isnull(df).sum()

结果:

区域          0
月份          0
降雨量(mm)     0
降雨距平(mm)    1
观测站         0
dtype: int64

仅一个缺失值数据,可直接删除:

df.dropna(inplace=True)

计算所有观测站降雨量相对往年的比较

计算降雨量比往年高,跟往年比无变化,以及比往年低的次数分别是多少:

rainfall_high = df.eval('`降雨距平(mm)` > 0').value_counts().get(True, 0)
rainfall_equal = df.eval('`降雨距平(mm)` == 0').value_counts().get(True, 0)
rainfall_low = df.eval('`降雨距平(mm)` < 0').value_counts().get(True, 0)
print(rainfall_high, rainfall_equal, rainfall_low)
13 1 18

上面的结果中rainfall_high表示降雨量比往年平均水平高的次数,rainfall_equal表示降雨量比往年平均水平持平的次数,rainfall_low表示降雨量比往年平均水平低的次数。

于是分情况讨论生成第一段的报告:

p1 = f"{month}月份"
if rainfall_low == 0 or rainfall_high == 0:if rainfall_equal != 0:p1 += f"除{rainfall_equal}个观测站降雨量较往年无变化外,"if rainfall_high == 0:p1 += f"各气象观测站降雨量较往年均偏低。"elif rainfall_low == 0:p1 += f"各气象观测站降雨量较往年均偏高。"
else:#  10%以内差异认为是持平if rainfall_high > rainfall_low*1.1:p1 += f"大部分气象观测站降雨量较往年偏高。"elif rainfall_low > rainfall_high*1.1:p1 += f"大部分气象观测站降雨量较往年偏低。"else:p1 += f"各气象观测站降雨量较往年整体持平。"
p1

结果:

'11月份大部分气象观测站降雨量较往年偏低。'

计算各区域降雨量的极值

再生成第二段的报告:

p2 = ""
t = df['降雨量(mm)']
p2 += f"各区域降雨量在{t.min()}~{t.max()}mm之间,其中{df.loc[t.argmax(), '区域']}区域的降雨量最大,为{t.max()}mm。"
p2

结果:

'各区域降雨量在0.0~16.0mm之间,其中51a45区域的降雨量最大,为16.0mm。'

分观测站统计

让我脑袋疼的地方就是从这里的代码开始的,后面还有更复杂蛋疼的需求就不公布了。

对每个观测站分别统计哪些区域偏高,哪些区域持平,哪些区域偏低:

p3s = []
for station, tmp in df.groupby('观测站'):t = tmp['降雨量(mm)']p3 = f"各区域降雨量在{t.min()}~{t.max()}mm之间,"rainfall_high_mask = tmp.eval('`降雨距平(mm)` > 0')rainfall_equal_mask = tmp.eval('`降雨距平(mm)` == 0')rainfall_low_mask = tmp.eval('`降雨距平(mm)` < 0')rainfall_high = rainfall_high_mask.value_counts().get(True, 0)rainfall_equal = rainfall_equal_mask.value_counts().get(True, 0)rainfall_low = rainfall_low_mask.value_counts().get(True, 0)
#     print(rainfall_high, rainfall_equal, rainfall_low)if rainfall_low == 0 or rainfall_high == 0:if rainfall_equal != 0:p3 += '除'p3 += '、'.join(tmp.loc[rainfall_equal_mask, '区域']+'区域')p3 += "降雨量较往年无变化外,"if rainfall_high == 0:p3 += f"各区域降雨量均较往年偏低"elif rainfall_low == 0:p3 += f"各区域降雨量均较往年偏高"t = tmp['降雨距平(mm)'].abs()p3 += f"{t.min()}~{t.max()}mm;"else:if rainfall_equal != 0:p3 += '除'p3 += '、'.join(tmp.loc[rainfall_equal_mask, '区域']+'区域')p3 += "降雨量较往年无变化,"#  10%以内差异认为是持平if rainfall_high > rainfall_low*1.1:if rainfall_equal == 0:p3 += '除'p3 += '、'.join(tmp.loc[rainfall_low_mask, '区域']+'区域')p3 += "降雨量较往年偏低"t = tmp.loc[rainfall_low_mask, '降雨距平(mm)'].abs()if t.shape[0] > 1:p3 += f"{t.min()}~{t.max()}mm"else:p3 += f"{t.min()}mm"p3 += "外,"t = tmp.loc[rainfall_high_mask, '降雨距平(mm)'].abs()p3 += f"其余各区域降雨量较往年偏高{t.min()}~{t.max()}mm;"elif rainfall_low > rainfall_high*1.1:if rainfall_equal == 0:p3 += '除'p3 += '、'.join(tmp.loc[rainfall_high_mask, '区域']+'区域')p3 += "降雨量较往年偏高"t = tmp.loc[rainfall_high_mask, '降雨距平(mm)'].abs()if t.shape[0] > 1:p3 += f"{t.min()}~{t.max()}mm"else:p3 += f"{t.min()}mm"p3 += "外,"t = tmp.loc[rainfall_low_mask, '降雨距平(mm)'].abs()p3 += f"其余各区域降雨量较往年偏低{t.min()}~{t.max()}mm;"else:if rainfall_equal != 0:p3 = p3[:-1]+'外,'p3 += f"各区域降雨量较往年偏高和偏低的数量持平,其中"p3 += '、'.join(tmp.loc[rainfall_low_mask, '区域']+'区域')p3 += "降雨量较往年偏低"t = tmp.loc[rainfall_low_mask, '降雨距平(mm)'].abs()if t.shape[0] > 1:p3 += f"{t.min()}~{t.max()}mm,"else:p3 += f"{t.min()}mm,"p3 += '、'.join(tmp.loc[rainfall_high_mask, '区域']+'区域')p3 += "降雨量较往年偏高"t = tmp.loc[rainfall_high_mask, '降雨距平(mm)'].abs()if t.shape[0] > 1:p3 += f"{t.min()}~{t.max()}mm;"else:p3 += f"{t.min()}mm;"p3s.append([station, p3])
p3s[-1][-1] = p3s[-1][-1][:-1]+"。"
p3s

结果:

[['A站','各区域降雨量在0.0~16.0mm之间,除548ad区域、1bafe区域、51a45区域、53f42区域降雨量较往年偏高0.1~7.41mm外,其余各区域降雨量较往年偏低0.4~3.4mm;'],['B站','各区域降雨量在0.0~5.3mm之间,除54ac3区域降雨量较往年无变化外,各区域降雨量较往年偏高和偏低的数量持平,其中16d40区域、592ac区域降雨量较往年偏低0.2~0.5mm,32046区域、4e6f0区域降雨量较往年偏高0.5~1.1mm;'],['C站', '各区域降雨量在1.3~3.5mm之间,除3722c区域降雨量较往年偏高1.4mm外,其余各区域降雨量较往年偏低0.6~2.9mm;'],['D站','各区域降雨量在0.0~5.5mm之间,各区域降雨量较往年偏高和偏低的数量持平,其中66955区域、7639e区域、1c5ff区域降雨量较往年偏低0.9~3.1mm,2d91d区域、78896区域、25464区域降雨量较往年偏高0.9~1.6mm;'],['E站', '各区域降雨量在7.3~13.6mm之间,各区域降雨量均较往年偏高4.0~9.1mm。']]

可能是我还没有想出较好的封装方式导致代码变得这么复杂,如果有巧妙解决这个问题方法的朋友,希望能够一起探讨。

将组织好的文本写入到word文档中

word模板文件docxtemplate.docx的内容:

一、{{ month }}月各气象观测站降雨量实况
(一)降水
{{ p1 }}
{{ p2 }}
{%p for station,p3 in p3s %}
{{ station }}:{{ p3 }}
{%p endfor %}

即:

image-20210103110456765

python渲染代码:

from docxtpl import DocxTemplatetpl = DocxTemplate("docxtemplate.docx")
context = {'month': month,'p1': p1,'p2': p2,'p3s': p3s,
}
tpl.render(context)
tpl.save("11月降雨量报告.docx")

执行完毕,得到word报告:

image-20210103110602273

这篇关于自动根据数据生成降雨量实况Word报告的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/279891

相关文章

Spring Boot项目中结合MyBatis实现MySQL的自动主从切换功能

《SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能》:本文主要介绍SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能,本文分步骤给大家介绍的... 目录原理解析1. mysql主从复制(Master-Slave Replication)2. 读写分离3.

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties