大家好!我是虎哥。
身為資料分析師,我們需要經常製作統計分析圖表。但是報表太多的時候往往需要花我們大部分時間來製作報表。這耽誤了我們利用大量的時間進行數據分析。但是身為資料分析師我們應該盡可能去挖掘表格圖表資料背後隱藏關聯訊息,而不是簡單的統計表格製作圖表再發送報表。
自動化總是能夠很好的節省時間,提高我們的工作效率。讓我們的程式編程盡可能的降低每個功能實現程式碼的耦合性,更好的維護程式碼。這樣我們會節省很多時間讓我們有空去做更多有價值、有意義的工作。
編碼實現效果正確無誤的話是可以一直沿用的,如果是人為來操作的話反而可能會犯一些錯誤。交給固定的程序來做更讓人放心,需求變更時只修改部分程式碼即可解決問題。
首先我們需要根據業務需求來製定我們所需要的報表,並不是每個報表都需要進行自動化的,一些複雜二次開發的指標數據要實現自動化程式設計的比較複雜的,而且可能會隱藏著各種BUG。所以我們需要對我們工作所要用到的報表的特性進行歸納,以下是我們需要綜合考慮的幾個方面:
對於一些業務上經常需要用到的表,這些表我們可能要納入自動化程序的範圍。例如客戶資訊清單、銷售流量報表、業務流失報表、環比同比報表等。
這些使用頻率較高的報表,都很有必要進行自動化。對於那些偶爾需要使用的報表,或是二次開發指標,需要複製統計的報表,這些報表就沒必要實現自動化了。
這就相當於成本和利率一樣,若是有些報表自動化實現困難,還超過了我們普通統計分析所需的時間,就沒必要去實現自動化。所以開始自動化工作的時候要衡量一下開發腳本所耗費的時間和人工做表所耗費的時間哪個更短了。當然我會提供一套實作方案,但只對一些常用簡單的報表。
對於我們報表每個流程和步驟,每個公司都有不同,我們需要根據業務場景去編碼實現各個步驟功能。所以我們製作的流程應該是符合業務邏輯的,製作的程式也應該是符合邏輯的。
首先我們需要知道我們需要什麼指標:
指標
反映某一資料指標的整體大小
相鄰時間段內的指標直接作差
相鄰時間段內某一共同時間點上指標的比較
我們拿一個簡單的報表來進行模擬實作:
首先我們要了解我們的資料是從哪裡來的,也就是資料來源。我們最終的資料處理都是轉換為DataFrame來進行分析的,所以需要將資料來源轉換為DataFrame形式:
import pandas as pd import json import pymysql from sqlalchemy import create_engine # 打开数据库连接 conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='xxxx', charset = 'utf8' ) engine=create_engine('mysql+pymysql://root:xxxx@localhost/mysql?charset=utf8') def read_excel(file): df_excel=pd.read_excel(file) return df_excel def read_json(file): with open(file,'r')as json_f: df_json=pd.read_json(json_f) return df_json def read_sql(table): sql_cmd ='SELECT * FROM %s'%table df_sql=pd.read_sql(sql_cmd,engine) return df_sql def read_csv(file): df_csv=pd.read_csv(file) return df_csv
以上程式碼皆經過測試可以正常使用,但是pandas的read函數針對不同的形式的檔案讀取,其read函數參數也有不同的意義,需要直接根據表格的形式來調整。
其他read函數將會在文章寫完之後後續補上,除了read_sql需要連接資料庫之外,其他的都是比較簡單的。
我們以使用者資訊為例:
我们需要统计的指标为:
#将城市空值的一行删除 df=df[df['city_num'].notna()] #删除error df=df.drop(df[df['city_num']=='error'].index) #统计df = df.city_num.value_counts()
我们仅获取前10名的城市就好了,封装为饼图:
def pie_chart(df): #将城市空值的一行删除 df=df[df['city_num'].notna()] #删除error df=df.drop(df[df['city_num']=='error'].index) #统计 df = df.city_num.value_counts() df.head(10).plot.pie(subplots=True,figsize=(5, 6),autopct='%.2f%%',radius = 1.2,startangle = 250,legend=False) pie_chart(read_csv('user_info.csv'))
将图表保存起来:
plt.savefig('fig_cat.png')
要是你觉得matplotlib的图片不太美观的话,你也可以换成echarts的图片,会更加好看一些:
pie = Pie() pie.add("",words) pie.set_global_opts(title_opts=opts.TitleOpts(title="前十地区")) #pie.set_series_opts(label_opts=opts.LabelOpts(user_df)) pie.render_notebook()
封装后就可以直接使用了:
def echart_pie(user_df): user_df=user_df[user_df['city_num'].notna()] user_df=user_df.drop(user_df[user_df['city_num']=='error'].index) user_df = user_df.city_num.value_counts() name=user_df.head(10).index.tolist() value=user_df.head(10).values.tolist() words=list(zip(list(name),list(value))) pie = Pie() pie.add("",words) pie.set_global_opts(title_opts=opts.TitleOpts(title="前十地区")) #pie.set_series_opts(label_opts=opts.LabelOpts(user_df)) return pie.render_notebook() user_df=read_csv('user_info.csv') echart_pie(user_df)
可以进行保存,可惜不是动图:
from snapshot_selenium import snapshot make_snapshot(snapshot,echart_pie(user_df).render(),"test.png")
保存为网页的形式就可以自动加载JS进行渲染了:
echart_pie(user_df).render('problem.html') os.system('problem.html')
做出来的一系列报表一般都要发给别人看的,对于一些每天需要发送到指定邮箱或者需要发送多封报表的可以使用Python来自动发送邮箱。
在Python发送邮件主要借助到smtplib和email这个两个模块。
不同种类的邮箱服务器连接地址不一样,大家根据自己平常使用的邮箱设置相应的服务器进行连接。这里博主用网易邮箱展示:
首先需要开启POP3/SMTP/IMAP服务:
之后便可以根据授权码使用python登入了。
import smtplib from email import encoders from email.header import Header from email.utils import parseaddr,formataddr from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText #发件人邮箱 asender="fanstuck@163.com" #收件人邮箱 areceiver="1079944650@qq.com" #抄送人邮箱 acc="fanstuck@163.com" #邮箱主题 asubject="谢谢关注" #发件人地址 from_addr="fanstuck@163.com" #邮箱授权码 password="####" #邮件设置 msg=MIMEMultipart() msg['Subject']=asubject msg['to']=areceiver msg['Cc']=acc msg['from']="fanstuck" #邮件正文 body="你好,欢迎关注fanstuck,您的关注就是我继续创作的动力!" msg.attach(MIMEText(body,'plain','utf-8')) #添加附件 htmlFile = 'C:/Users/10799/problem.html' html = MIMEApplication(open(htmlFile , 'rb').read()) html.add_header('Content-Disposition', 'attachment', filename='html') msg.attach(html) #设置邮箱服务器地址和接口 smtp_server="smtp.163.com" server = smtplib.SMTP(smtp_server,25) server.set_debuglevel(1) #登录邮箱 server.login(from_addr,password) #发生邮箱 server.sendmail(from_addr,areceiver.split(',')+acc.split(','),msg.as_string()) #断开服务器连接 server.quit()
运行测试:
下载文件:
完全没问题!!!
以上是Python自動化辦公室小程式:實現報表自動化和自動傳送到目的信箱的詳細內容。更多資訊請關注PHP中文網其他相關文章!