文章目录
14.1 利用Python实现报表自动化
14.1.1 为什么要进行报表自动化
要衡量变为自动化的时间与手动的时间
对象是否成熟,固定
14.1.3 如何实现报表自动化
导入数据源
import pandas as pd
import numpy as np
from datetime import datetime
data = pd.read_csv(r"C:\Users\leadi\Python\01.python\input\order-14.1.csv",encoding="gbk")
data.head()
#data.info()
判断时间的列的类型
type(data["成交时间"])
type(data["成交时间"][0])
pandas.core.series.Series
str
# 每个时间为字符串,非时间序列
读入文件时,需要声明为时间序列
重新读入
data = pd.read_csv(r"C:\Users\leadi\Python\01.python\input\order-14.1.csv",encoding="gbk",parse_dates = ["成交时间"])
#测试为,时间序列
type(pd.to_datetime(data["成交时间"]))
type(data["成交时间"][0])
输出
pandas._libs.tslibs.timestamps.Timestamp
选择本月的数据
this_month = data[(data["成交时间"] >= datetime(2018,2,1)) & (data["成交时间"] <= datetime(2018,2,28))]
this_month
本月
This_month = data[(data["成交时间"] >= datetime(2018,2,1)) & (data["成交时间"] <= datetime(2018,2,28))]
This_month
sale_1 = (This_month["销量"]*This_month["单价"]).sum()
traffic_1 = This_month["订单ID"].drop_duplicates().count()
s_t_1 = sale_1/traffic_1 # 单价
print("本月销售额为:{:.2f},客流量为:{},客单价为:{:.2f}".format(sale_1,traffic_1,s_t_1))
输出结果
本月销售额为:10412.78,客流量为:343,客单价为:30.36
下一个月
Last_month = data[(data["成交时间"] >= datetime(2018,1,1)) & (data["成交时间"] <= datetime(2018,1,31))]
Last_month
去年同月
same_month = data[(data["成交时间"] >= datetime(2017,2,1)) & (data["成交时间"] <= datetime(2017,2,28))]
same_month.head()
对于销售额,的计算方式一致,可以使用函数的方式,只需要输入数据
def get_month_data(data):
sale = (data["销量"]*data["单价"]).sum()
traffic = data["订单ID"].drop_duplicates().count()
s_t = sale/traffic # 单价
return (sale,traffic,s_t)
sale_1,traffic_1,s_t_1 = get_month_data(This_month)
sale_2,traffic_2,s_t_2 = get_month_data(This_month)
sale_3,traffic_3,s_t_3 = get_month_data(This_month)
print(sale_1,traffic_1,s_t_1)
print(sale_2,traffic_2,s_t_2)
print(sale_3,traffic_3,s_t_3)
输出:
10412.78007 343 30.357959387755105
10412.78007 343 30.357959387755105
10412.78007 343 30.357959387755105
生成表格
report = pd.DataFrame([[sale_1,traffic_1,s_t_1],[sale_2,traffic_2,s_t_2 ],[sale_3,traffic_3,s_t_3 ]],columns= ["本月累积","上月累积","去年同期"],index = ["销售额","客流量","客单价"])
report
14.2 自动发送电子邮件
import smtplib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
# 发件人邮箱,# 不写也不影响,下面有发件地址
asender = "abc@163.com"
# 收件人邮箱
arecevier = "efg@qq.com"
# 抄送人邮箱
acc = "efg@qq.com"
# 邮件主题
asubject = "这是测试邮件"
# 发件人地址
from_addr = "abc@163.com"
# 邮箱密码(授权码)# 经测试,不能使用密码,只能使用授权码
password = "aaaaa"
# 邮件设置
msg = MIMEMultipart()
msg["Subject"] = asubject
msg["to"] = arecevier
msg["Cc"] = acc
msg["from"] = "leadingsci" # 更改为“地球人”
# 邮件正文
body = "你好,这是一封测试的邮件"
# 添加邮件正文
msg.attach(MIMEText(body,"plain","utf-8"))
# 添加附件
# 注意,这里的文件路径是分割线
xlsxpart = MIMEApplication(open(r"C:\Users\leadi\Python\01.python\input\loan.csv","rb").read())
xlsxpart.add_header("Content-Disposition","attachment",filename = "这是附件.xlsx")
msg.attach(xlsxpart)
# 设置邮箱服务器地址及端口
smtip_server = "smtp.163.com"
server = smtplib.SMTP(smtip_server,25)
server.set_debuglevel(1)
# 登录邮箱
server.login(from_addr,password)
# 发送邮件
server.sendmail(from_addr,arecevier.split(",")+acc.split(","),msg.as_string())
因此,前面是邮箱名,按邮箱的通讯录的名片显示,后面是定义的昵称
如果需要发送多封邮件,则将上述邮件国产定义成一个函数,把收件人其他内容生成一个列表,然后遍历每一个收件人,最后调用发送邮件函数进行多邮件发送
14.3 假如你是某连锁超市的数据分析师
# 导入数据源,成交时间排序
data = pd.read_csv(r"C:/Users/leadi/Python/01.python/input/order-14.1.csv",encoding="gbk",parse_dates = ["成交时间"])
data.head()
# 哪些类别比较畅销
# 根据ID,对销量进行汇总,然后按销量排序,的前10
data.groupby("类别ID")["销量"].sum().reset_index().sort_values(by = "销量",ascending = False).head(10)
# 哪些商品比较畅销
pd.pivot_table(data,index = "商品ID",values = "销量",aggfunc = "sum").reset_index().sort_values(by = "销量",ascending = False).head(10)
# 不同门店的销售额占比
data["销售额"] = data["销量"] * data["单价"]
data.head()
data.groupby("门店编号")["销售额"].sum()
p = (data.groupby("门店编号")["销售额"].sum()/data["销售额"].sum()).plot.pie()
p
# 哪些时间段是超市的客流高峰期
from time import strftime
data["小时"] = data["成交时间"].map(lambda x :x,strftime("%H"))
data["小时"]
# 对小时和订单去重
traffic = data[["小时","订单ID"]].drop_duplicates()
traffic
traffic.groupby("小时")["订单ID"].count().plot()
可有对时间,进行时间序列格式,然后进行进行销量排序。或时间排序作图。
14.4 假如你是某银行的数据分析师
data = pd.read_csv(r"C:/Users/leadi/Python/01.python/input/loan.csv",encoding="gbk")
data.head()
data.info()
# 填缺失值
data = data.fillna({"月收入":data["月收入"].mean()})
data.info()
# 是不是收入越高的人坏账率越低
cut_bins = [0,5000,10000,15000,20000,100000]
income_cut = pd.cut(data["月收入"],cut_bins)
income_cut
all_income_user = data["好坏客户"].groupby(income_cut).count()
bad_income_user = data["好坏客户"].groupby(income_cut).sum()
bad_rate = bad_income_user/all_income_user
bad_rate
# 输出
月收入
(0, 5000] 0.087543
(5000, 10000] 0.058308
(10000, 15000] 0.041964
(15000, 20000] 0.041811
(20000, 100000] 0.053615
Name: 好坏客户, dtype: float64
bad_rate.plot.bar()
低收入,坏账较高
# 年龄和h坏账率有什么关系
age_cut = pd.cut(data["年龄"],6)
all_age_user = data["好坏客户"].groupby(age_cut).count()
bad_age_user = data["好坏客户"].groupby(age_cut).sum()
bad_rate = bad_age_user/all_age_user
bad_rate
bad_rate.plot.bar()
18-36岁坏帐较高
# 家庭人口数量和坏账率的关系
all_age_user = data.groupby("家属数量")["好坏客户"].count()
bad_age_user = data.groupby("家属数量")["好坏客户"].sum()
bad_rate = bad_age_user/all_age_user
bad_rate.plot.bar()