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

相关文章

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装