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

相关文章

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分