干货|利用Python自动根据数据生成降雨量统计分析报告

Irene181 等级 1334 0 0

干货|利用Python自动根据数据生成降雨量统计分析报告

作者:小小明

简介:Pandas数据处理专家,10余年编码经验,至今已帮助过成千上万名数据从业者解决工作实际遇到的问题,其中数据处理和办公自动化问题涉及的行业包括会计、HR、气象、金融等等,现为菜J学Python核心技术团队成员之一。

点击上方“Python爬虫与数据挖掘”,进行关注

回复“书籍”即可获赠Python从入门到进阶共10本电子书

今夜偏知春气暖,虫声新透绿窗纱。

大家好,我是J哥。

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

后台回复「降雨」二字,可领取本文所用数据集和Word模板,便于大家用Python测试。

先看看需求吧:

干货|利用Python自动根据数据生成降雨量统计分析报告

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

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

1

数据读取



import pandas as pd  

df = pd.read\_csv("11月份数据.csv", encoding='gbk')  
# 当前统计月份  
month = 11  
df = df.query('月份==@month')  
df.head(10)  


预览数据:

干货|利用Python自动根据数据生成降雨量统计分析报告

2

异常数据过滤

查看缺失值数量:



pd.isnull(df).sum()  


结果:



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


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



df.dropna(inplace=True)  


3

计算观测站降雨量相对往年的变化

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



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月份大部分气象观测站降雨量较往年偏低。'  


4

计算各区域降雨量的极值

再生成第二段的报告:



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。'  


5

分观测站统计

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

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



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  


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

6

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

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



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


即:

干货|利用Python自动根据数据生成降雨量统计分析报告

Python渲染代码:



from docxtpl import DocxTemplate  

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


执行完毕,得到Word统计分析报告:

干货|利用Python自动根据数据生成降雨量统计分析报告

**-----**------**-----**---**** End **-----**--------**-----**-****

往期精彩文章推荐:

干货|利用Python自动根据数据生成降雨量统计分析报告

欢迎各位大佬点击链接加入群聊【helloworld开发者社区】:https://jq.qq.com/?_wv=1027&k=mBlk6nzX进群交流IT技术热点。

本文转自 https://mp.weixin.qq.com/s/oMG7zFZgGN8NahjkkqR13g,如有侵权,请联系删除。

收藏
评论区

相关推荐

15. Python 程序运行速度如何提高十倍?第一遍滚雪球学 Python 收工
本篇文章将给大家介绍 Python 多线程与多进程相关知识,学习完该知识点之后,你的 Python 程序将进入另一个高峰。 <center<font colorred缓解一下视疲劳</font</center 15. Python 程序运行速度如何提高十倍?第一遍滚雪球学 Python 收工(https://imghelloworld.oss
盘点一款Python二级考试模拟软件,带你轻松过关二级Python考试
大家好,我是Python进阶者。今天给大家讲的这个软件,主要是想让大家通过这个软件能将自己的Python基础进一步提高。一、前言相信有些小伙伴学习Python有一段时日,但是又不知道自己的Python基础学的如何,这个时候就需要一款神器来检测一下自己的Python基础了。要想检测自己的Python功力最直观的方法当然是做题了,至于做什么题了我们就不得而知了,
(二十九) 初遇python OOP面向对象编程
**各位读者大大们大家好,今天学习python的面向对象编程-属性装饰器,并记录学习过程欢迎大家一起交流分享。** ![](https://oscimg.oschina.net/oscnet/2bffb0067c4967eca2188c825154f2e4a5d.jpg) **新建一个python文件命名为py3\_oop6.py,在这个文件中进行操作代
5 行 Python 代码调用电脑摄像头
**前提:** 确保 python 中安装了 opencv-python 模块。如果没有安装,可以参考:[https://pypi.org/project/opencv-python/](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fpypi.org%2Fproject%2Fopencv
055 Python第三方库安装
\[TOC\] 一、概述 ==== * 看见更大的Python世界 * 第三方库的pip安装方法 * 第三方库的集成安装方法 * 第三方库的文件安装方法 二、看见更大的Python世界 =============== 2.1 Python社区 ------------ \>13万个第三方库:<a target='\_blank' h
2019独角兽企业重金招聘Python工程师标准
很多盆友一定有这样的疑问: **Python****是什么?** **学会了Python可以做什么?** **为什么人人都应该懂Python?** ![](https://oscimg.oschina.net/oscnet/f7ddd56eca5709e45b4b95cc1d9c9bc5d20.jpg) 别急,我来科普啦~ Python是一门面向
055 Python第三方库安装
\[TOC\] 一、概述 ==== * 看见更大的Python世界 * 第三方库的pip安装方法 * 第三方库的集成安装方法 * 第三方库的文件安装方法 二、看见更大的Python世界 =============== 2.1 Python社区 ------------ \>13万个第三方库:<a target='\_blank' h
2019独角兽企业重金招聘Python工程师标准
很多盆友一定有这样的疑问: **Python****是什么?** **学会了Python可以做什么?** **为什么人人都应该懂Python?** ![](https://oscimg.oschina.net/oscnet/f7ddd56eca5709e45b4b95cc1d9c9bc5d20.jpg) 别急,我来科普啦~ Python是一门面向
FreeBSD python安装MySQL
fetch https://pypi.python.org/packages/source/M/MySQL-python/MySQL-python-1.2.4.zip unzip MySQL-python-1.2.4.zip cd MySQL-python-1.2.4 python setup.py install ln -s /usr/loca
Python 3 教程
Python 3 教程 =========== ![python3](https://www.runoob.com/wp-content/uploads/2014/05/python3.png) Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,
Python中的基础数据类型(String,Number)及其常用用法简析
点击上方“ **Python爬虫与数据挖掘** ”,进行关注 回复“**书籍**”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 寄意寒星荃不察,我以我血荐轩辕。 Python中的基础数据类型 ============== 前言 -- 哈喽,各位小伙伴们,相信大家和我一样,在开始接触Python这门语言的时候,会遇到很多困
Python向来以慢著称,为啥Instagram却唯独钟爱它?
PyCon 是全世界最大的以 Python 编程语言 为主题的技术大会,大会由 Python 社区组织,每年举办一次。在 Python 2017 上,Instagram 的工程师们带来了一个有关 Python 在 Instagram 的主题演讲,同时还分享了 Instagram 如何将整个项目运行环境升级到 Python 3 的故事。本文为该次演讲的内容摘要
Python环境搭建—安利Python小白的Python和Pycharm安装详细教程
人生苦短,我用Python。众所周知,Python目前越来越火,学习Python的小伙伴也越来越多。最近看到群里的小伙伴经常碰到不会安装Python或者不知道去哪下载Python安装包等系列问题,为了方便大家学习Python,小编整理了一套Python和Pycharm安装详细教程,只要大家按照这个步骤来,就可以轻松的搞定Python和Pycharm的安装了。
Python真是什么都能干!今天实现一下自动打开和运行电脑软件!
最近做项目,要用到软件自动化的操作,正好更大家分享一下! ![](https://img2018.cnblogs.com/blog/1627425/201909/1627425-20190911205328415-1196306902.png) 先看看Python操作: ============ ![都说了Python很牛逼!教大家用Pytho
Python解释器和IPython
简介 == 今天给大家介绍一下Python的一个功能非常强大的解释器IPython。虽然Python本身自带解释器,但是相对而言IPython的功能更加的强大。 Python解释器 ========= Python是自带解释器的,我们在命令行输入python即可进入python的解释器环境: $> pythonPython 2.7.15 (d