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

作者:小小明

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

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

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

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

大家好,我是J哥。

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

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

先看看需求吧:

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

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

1

数据读取

1 2 3import pandas as pd 4 5df = pd.read\_csv("11月份数据.csv", encoding='gbk') 6# 当前统计月份 7month = 11 8df = df.query('月份==@month') 9df.head(10) 10 11 12

预览数据:

2

异常数据过滤

查看缺失值数量:

1 2 3pd.isnull(df).sum() 4 5 6

结果:

1 2 3区域          0 4月份          0 5降雨量(mm)     0 6降雨距平(mm)    1 7观测站         0 8dtype: int64 9 10 11

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

1 2 3df.dropna(inplace=True) 4 5 6

3

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

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

1 2 3rainfall\_high = df.eval('\`降雨距平(mm)\` > 0').value\_counts().get(True, 0) 4rainfall\_equal = df.eval('\`降雨距平(mm)\` == 0').value\_counts().get(True, 0) 5rainfall\_low = df.eval('\`降雨距平(mm)\` < 0').value\_counts().get(True, 0) 6print(rainfall\_high, rainfall\_equal, rainfall\_low) 7 8 9
1 2 313 1 18 4 5 6

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

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

1 2 3p1 = f"{month}月份" 4if rainfall\_low == 0 or rainfall\_high == 0: 5    if rainfall\_equal != 0: 6        p1 += f"除{rainfall\_equal}个观测站降雨量较往年无变化外," 7    if rainfall\_high == 0: 8        p1 += f"各气象观测站降雨量较往年均偏低。" 9    elif rainfall\_low == 0: 10        p1 += f"各气象观测站降雨量较往年均偏高。" 11else: 12    #  10%以内差异认为是持平 13    if rainfall\_high > rainfall\_low\*1.1: 14        p1 += f"大部分气象观测站降雨量较往年偏高。" 15    elif rainfall\_low > rainfall\_high\*1.1: 16        p1 += f"大部分气象观测站降雨量较往年偏低。" 17    else: 18        p1 += f"各气象观测站降雨量较往年整体持平。" 19p1 20 21 22

结果:

1 2 3'11月份大部分气象观测站降雨量较往年偏低。' 4 5 6

4

计算各区域降雨量的极值

再生成第二段的报告:

1 2 3p2 = "" 4= df\['降雨量(mm)'\] 5p2 += f"各区域降雨量在{t.min()}~{t.max()}mm之间,其中{df.loc\[t.argmax(), '区域'\]}区域的降雨量最大,为{t.max()}mm。" 6p2 7 8 9

结果:

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

5

分观测站统计

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

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

1 2 3p3s = \[\] 4for station, tmp in df.groupby('观测站'): 5    t = tmp\['降雨量(mm)'\] 6    p3 = f"各区域降雨量在{t.min()}~{t.max()}mm之间," 7    rainfall\_high\_mask = tmp.eval('\`降雨距平(mm)\` > 0') 8    rainfall\_equal\_mask = tmp.eval('\`降雨距平(mm)\` == 0') 9    rainfall\_low\_mask = tmp.eval('\`降雨距平(mm)\` < 0') 10 11    rainfall\_high = rainfall\_high\_mask.value\_counts().get(True, 0) 12    rainfall\_equal = rainfall\_equal\_mask.value\_counts().get(True, 0) 13    rainfall\_low = rainfall\_low\_mask.value\_counts().get(True, 0) 14#     print(rainfall\_high, rainfall\_equal, rainfall\_low) 15 16    if rainfall\_low == 0 or rainfall\_high == 0: 17        if rainfall\_equal != 0: 18            p3 += '除' 19            p3 += '、'.join(tmp.loc\[rainfall\_equal\_mask, '区域'\]+'区域') 20            p3 += "降雨量较往年无变化外," 21        if rainfall\_high == 0: 22            p3 += f"各区域降雨量均较往年偏低" 23        elif rainfall\_low == 0: 24            p3 += f"各区域降雨量均较往年偏高" 25        t = tmp\['降雨距平(mm)'\].abs() 26        p3 += f"{t.min()}~{t.max()}mm;" 27    else: 28        if rainfall\_equal != 0: 29            p3 += '除' 30            p3 += '、'.join(tmp.loc\[rainfall\_equal\_mask, '区域'\]+'区域') 31            p3 += "降雨量较往年无变化," 32        #  10%以内差异认为是持平 33        if rainfall\_high > rainfall\_low\*1.1: 34            if rainfall\_equal == 0: 35                p3 += '除' 36            p3 += '、'.join(tmp.loc\[rainfall\_low\_mask, '区域'\]+'区域') 37            p3 += "降雨量较往年偏低" 38            t = tmp.loc\[rainfall\_low\_mask, '降雨距平(mm)'\].abs() 39            if t.shape\[0\] > 1: 40                p3 += f"{t.min()}~{t.max()}mm" 41            else: 42                p3 += f"{t.min()}mm" 43            p3 += "外," 44            t = tmp.loc\[rainfall\_high\_mask, '降雨距平(mm)'\].abs() 45            p3 += f"其余各区域降雨量较往年偏高{t.min()}~{t.max()}mm;" 46        elif rainfall\_low > rainfall\_high\*1.1: 47            if rainfall\_equal == 0: 48                p3 += '除' 49            p3 += '、'.join(tmp.loc\[rainfall\_high\_mask, '区域'\]+'区域') 50            p3 += "降雨量较往年偏高" 51            t = tmp.loc\[rainfall\_high\_mask, '降雨距平(mm)'\].abs() 52            if t.shape\[0\] > 1: 53                p3 += f"{t.min()}~{t.max()}mm" 54            else: 55                p3 += f"{t.min()}mm" 56            p3 += "外," 57            t = tmp.loc\[rainfall\_low\_mask, '降雨距平(mm)'\].abs() 58            p3 += f"其余各区域降雨量较往年偏低{t.min()}~{t.max()}mm;" 59        else: 60            if rainfall\_equal != 0: 61                p3 = p3\[:\-1\]+'外,' 62            p3 += f"各区域降雨量较往年偏高和偏低的数量持平,其中" 63            p3 += '、'.join(tmp.loc\[rainfall\_low\_mask, '区域'\]+'区域') 64            p3 += "降雨量较往年偏低" 65            t = tmp.loc\[rainfall\_low\_mask, '降雨距平(mm)'\].abs() 66            if t.shape\[0\] > 1: 67                p3 += f"{t.min()}~{t.max()}mm," 68            else: 69                p3 += f"{t.min()}mm," 70            p3 += '、'.join(tmp.loc\[rainfall\_high\_mask, '区域'\]+'区域') 71            p3 += "降雨量较往年偏高" 72            t = tmp.loc\[rainfall\_high\_mask, '降雨距平(mm)'\].abs() 73            if t.shape\[0\] > 1: 74                p3 += f"{t.min()}~{t.max()}mm;" 75            else: 76                p3 += f"{t.min()}mm;" 77    p3s.append(\[station, p3\]) 78p3s\[\-1\]\[\-1\] = p3s\[\-1\]\[\-1\]\[:\-1\]+"。" 79p3s 80 81 82

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

6

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

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

1 2 3一、{{ month }}月各气象观测站降雨量实况 4(一)降水 5{{ p1 }} 6{{ p2 }} 7{%for station,p3 in p3s %} 8{{ station }}:{{ p3 }} 9{%p endfor %} 10 11 12

即:

Python渲染代码:

1 2 3from docxtpl import DocxTemplate 4 5tpl = DocxTemplate("docxtemplate.docx") 6context = { 7    'month': month, 8    'p1': p1, 9    'p2': p2, 10    'p3s': p3s, 11} 12tpl.render(context) 13tpl.save("11月降雨量报告.docx") 14 15 16

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

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

往期精彩文章推荐:

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

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

点赞
收藏

评论区

加载中...

相关推荐

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

盘点最重要的7个Python库

点击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书导读:对于那些对Python数据生态系统不太熟悉的人士,我将简要地介绍一部分重要的库。作者:韦斯·麦金尼(WesMcKinney)译者:徐敬来源:大数据DT(ID:hzdashuju)01NumPyhttp://numpy

Pandas专家总结:指定样式保存excel数据的 “N种” 姿势!

作者:小小明简介:Pandas数据处理专家,10余年编码经验,至今已帮助过百名以上数据从业人员解决工作实际遇到的问题,其中数据处理和办公自动化问题涉及的行业包括会计、审计、HR、气象工作人员、教师、律师、运营,以及各行业的数据分析师和专做数据分析案例的公众号号主。若你在数据处理的问题上遇到什么困难,欢迎与我交流。目录准备数据

Python爬取所有人位置信息,制作任意区域人流量显示图

击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤衣裳已施行看尽,针线犹存未忍开。最近偶然看到了腾讯的大数据星云图,非常漂亮,如下图:!(https://oscimg.oschina.net/oscnet/6dc6022d4dfb49

Python分析《哈哈哈哈哈》47687条弹幕,看看大家都在说些啥!

点击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤归山深浅去,须尽丘壑美。!(https://oscimg.oschina.net/oscnet/5a50ee167263416384471dc0bf419cee.png)图片来源:豆瓣

10行Python代码自动清理电脑内重复文件,解放双手!

点击上方“Python爬虫与数据挖掘”,进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤世间行乐亦如此,古来万事东流水。!(https://oscimg.oschina.net/oscnet/da5385ecbd59492aa127c14a1a5b807c.jpg)(h