自动根据数据生成降雨量实况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

相关文章

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Navicat数据表的数据添加,删除及使用sql完成数据的添加过程

《Navicat数据表的数据添加,删除及使用sql完成数据的添加过程》:本文主要介绍Navicat数据表的数据添加,删除及使用sql完成数据的添加过程,具有很好的参考价值,希望对大家有所帮助,如有... 目录Navicat数据表数据添加,删除及使用sql完成数据添加选中操作的表则出现如下界面,查看左下角从左

SpringBoot中4种数据水平分片策略

《SpringBoot中4种数据水平分片策略》数据水平分片作为一种水平扩展策略,通过将数据分散到多个物理节点上,有效解决了存储容量和性能瓶颈问题,下面小编就来和大家分享4种数据分片策略吧... 目录一、前言二、哈希分片2.1 原理2.2 SpringBoot实现2.3 优缺点分析2.4 适用场景三、范围分片

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模

浅析如何保证MySQL与Redis数据一致性

《浅析如何保证MySQL与Redis数据一致性》在互联网应用中,MySQL作为持久化存储引擎,Redis作为高性能缓存层,两者的组合能有效提升系统性能,下面我们来看看如何保证两者的数据一致性吧... 目录一、数据不一致性的根源1.1 典型不一致场景1.2 关键矛盾点二、一致性保障策略2.1 基础策略:更新数