import pandas as pd
import numpy as np
#读取数据
filename='E:\sale.xlsx'
xls=pd.ExcelFile(filename,dtype="object")
salesdf=xls.parse('Sheet1',dtype='object')
#打印出前5行数据
print(salesdf.head())
#数据大小,多少行多少列,注意shape后面不添加括号
print(salesdf.shape)
#数据类型:dtypes.后面也是不添加括号
print(salesdf.dtypes)
#数据清洗
#1)更改数据列头名字
"""
inplace=True是数据框本身会改动
inplace=False数据框本身不会变,而会创建一个改动后的新的数据框,默认的是flase
"""
dictnamecol={"购药时间":"销售时间"}
salesdf.rename(columns=dictnamecol,inplace=True)
print(salesdf.head())
#2) 缺失值处理
print("缺失前的数据大小:",salesdf.shape)
salesdf=salesdf.dropna(subset=["销售时间",'社保卡号'],how="any")
print("删除缺失后的大小:",salesdf.shape)
"""
数据类型的转换:字符串转为日期
销售数量和金额:字符串转为浮点型,有利于下面的describe进行统计,否则describe就会无法对销售数量和金额进行统计
"""
salesdf.loc[:,"销售数量"]=salesdf.loc[:,'销售数量'].astype("float")
salesdf.loc[:,"应收金额"]=salesdf.loc[:,'应收金额'].astype("float")
salesdf.loc[:,"实收金额"]=salesdf.loc[:,'实收金额'].astype("float")
#数据类型的转换
#定义一个函数,将列表中的字符串时间数据分列开,取第一个年月日,
def splitsaletime(timecolser):
timelist=[]
for value in timecolser:
datastr=value.split(" ")[0]
timelist.append(datastr)
timeser=pd.Series(timelist)
return timeser
#将excel中的第一行销售时间提取出来,运用到函数里面,再将提取出来的字符串年月日赋值给销售时间
timeser=salesdf.loc[:,'销售时间']
dataser=splitsaletime(timeser)
salesdf.loc[:,'销售时间']=dataser
"""
数据类型的转换:字符串转为日期
"""
#errors='coerce' 如果原始数据不符合日期的格式,转换后的值为空值NaT
#format 是原数据中的日期格式
salesdf.loc[:,'销售时间']=pd.to_datetime(salesdf.loc[:,"销售时间"],format='%Y-%m-%d',errors="coerce")
print(salesdf.dtypes)
#以上是销售时间从重命名,分列,获取年月日,再将年月日赋值给销售时间
#转换日期过程中不符合日期格式的数值会被转换为空值,
#这里删除列(销售时间,社保卡号)中为空的行
salesdf=salesdf.dropna(subset=['销售时间','社保卡号'],how='any')
print(salesdf.head())
#数据排序
"""
by:按哪一列排序
ascending=True,按照降序排列
ascending=False 按照升序排列
"""
#按照销售日期进行升序排列
salesdf=salesdf.sort_values(by="销售时间",ascending=True)
print(salesdf.head())
#经过重新排序后,index的索引列就会重新改变
#重命名行名(index):排序后的列索引值是之前的行号,需要修改成从0到N的按顺序的索引值
salesdf=salesdf.reset_index(drop=True)
print(salesdf.head())
#异常值处理
print(salesdf.describe())
#发现存在的销售数量<0的异常值
#删除异常值:通过条件筛选出数据
#查询条件
queryser=salesdf.loc[:,"销售数量"]>0
#应用查询条件
print("删除异常值前:",salesdf.shape)
salesdf=salesdf.loc[queryser,:]#布尔运算,因为上面的查询条件得到的是行,所以根据布尔索引行对应相应的行。
print("删除异常值后:",salesdf.shape)
#构建模型
#指标1:月平均消费次数
"""
总消费次数:同一天,同一个人的所有消费都算作是一次消费
根据列名(销售时间,社区卡号),如果这两个列值同时相同,只保留第一个
将重复的数据删除
"""
kpil_df=salesdf.drop_duplicates(subset=["销售时间",'社保卡号'])
#总得消费次数:有多少行
total=kpil_df.shape[0]
print("总得消费次数:",total)
#月份数
starttime=kpil_df.loc[0,"销售时间"]
endtime=kpil_df.loc[total-1,'销售时间']
days=(endtime-starttime).days
month=days//30
print("月份数:",month)
#业务指标1:月平均消费次数=总次数/月数
kpi1=total/month
print("月平均消费次数:",kpi1)
#业务指标2:月平均消费额
#因为总得金额是包含同一时间和同一个社保卡号的,因此是不能用kpi_df,应该用去重之前的sale_df
totalmoney=salesdf.loc[:,"实收金额"].sum()
monthmoney=totalmoney/month
print("月平均消费额:",monthmoney)
#业务指标3:客单价
'''
总消费额/总次数
'''
pct=totalmoney/total
print("客单价:",pct)
答案如下:
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
0 2018-01-01 星期五 001616528 236701 强力VC银翘片 6 82.8 69
1 2018-01-02 星期六 001616528 236701 清热解毒口服液 1 28 24.64
2 2018-01-06 星期三 0012602828 236701 感康 2 16.8 15
3 2018-01-11 星期一 0010070343428 236701 三九感冒灵 1 28 28
4 2018-01-15 星期五 00101554328 236701 三九感冒灵 8 224 208
(6578, 7)
购药时间 object
社保卡号 object
商品编码 object
商品名称 object
销售数量 object
应收金额 object
实收金额 object
dtype: object
销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
0 2018-01-01 星期五 001616528 236701 强力VC银翘片 6 82.8 69
1 2018-01-02 星期六 001616528 236701 清热解毒口服液 1 28 24.64
2 2018-01-06 星期三 0012602828 236701 感康 2 16.8 15
3 2018-01-11 星期一 0010070343428 236701 三九感冒灵 1 28 28
4 2018-01-15 星期五 00101554328 236701 三九感冒灵 8 224 208
缺失前的数据大小: (6578, 7)
删除缺失后的大小: (6575, 7)
销售时间 datetime64[ns]
社保卡号 object
商品编码 object
商品名称 object
销售数量 object
应收金额 object
实收金额 object
dtype: object
销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
0 2018-01-01 001616528 236701 强力VC银翘片 6 82.8 69
1 2018-01-02 001616528 236701 清热解毒口服液 1 28 24.64
2 2018-01-06 0012602828 236701 感康 2 16.8 15
3 2018-01-11 0010070343428 236701 三九感冒灵 1 28 28
4 2018-01-15 00101554328 236701 三九感冒灵 8 224 208
销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
0 2018-01-01 001616528 236701 强力VC银翘片 6 82.8 69
3436 2018-01-01 0010616728 865099 硝苯地平片(心痛定) 2 3.4 3
1190 2018-01-01 0010073966328 861409 非洛地平缓释片(波依定) 5 162.5 145
3859 2018-01-01 0010073966328 866634 硝苯地平控释片(欣然) 6 111 92.5
3888 2018-01-01 0010014289328 866851 缬沙坦分散片(易达乐) 1 26 23
销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
0 2018-01-01 001616528 236701 强力VC银翘片 6 82.8 69
1 2018-01-01 0010616728 865099 硝苯地平片(心痛定) 2 3.4 3
2 2018-01-01 0010073966328 861409 非洛地平缓释片(波依定) 5 162.5 145
3 2018-01-01 0010073966328 866634 硝苯地平控释片(欣然) 6 111 92.5
4 2018-01-01 0010014289328 866851 缬沙坦分散片(易达乐) 1 26 23
销售数量 应收金额 实收金额
count 6549.000000 6549.000000 6549.000000
mean 2.384486 50.449076 46.284370
std 2.375227 87.696401 81.058426
min -10.000000 -374.000000 -374.000000
25% 1.000000 14.000000 12.320000
50% 2.000000 28.000000 26.500000
75% 2.000000 59.600000 53.000000
max 50.000000 2950.000000 2650.000000
[6 rows x 7 columns]
删除异常值前: (6549, 7)
删除异常值后: (6506, 7)
总得消费次数: 5342
月份数: 5
月平均消费次数: 1068.4
月平均消费额: 60802.02199999957
客单价: 56.9094178210404
第四关:pandas分析实际案例-药店销售数据分析
猜你喜欢
转载自blog.csdn.net/qq_42787271/article/details/82702610
今日推荐
周排行