本文的数据源是朝阳区医院2016的销售数据,用python进行处理
要求的业务指标是:1)月均消费次数;2)月均消费金额;3)客单价;4)消费趋势
这几个指标主要判断了用户端的消费趋势,为了给医院更多的指导,再此基础上进行
了一定的扩展,个人增加了两个指标,也是为了多熟悉库的使用
5)列出各类药品售出数量的排名,这个指标可以指导医院多存储哪类药品,少存储哪
类药品,避免药物不足或过期
6)列出每周7天各有各有多少人来医院,这样可以提前安排每周各天的排班,避免某天
过了幸苦或空闲
![Uploading output_31_2_679026.png . . .]
数据分析过程:
一、预处理
1、读取数据
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df=pd.read_excel('朝阳医院2016年销售数据.xlsx',sheet_name='Sheel')
df[:3]
#2、删除缺失值
df=df.dropna(how='any',axis=0)
df[1:3]
time =df['购药时间']
time[:4]
0 2016-01-01 星期五
1 2016-01-02 星期六
2 2016-01-06 星期三
3 2016-01-11 星期一
Name: 购药时间, dtype: object
shebao=df['社保卡号']
shebao[:5]
0 1616528
1 1616528
2 10070343428
3 13389528
4 101554328
Name: 社保卡号, dtype: int64
#3.修改列名,中文名称是无法在dateframe中直接用字符串表示处出来
#改名
names=['time','cardNum','drugID','drugName','saleNum',
'virtuaiMone','actualMoney']
df.columns=names
4.排序,一般按照时间排序
由于时间格式是“2016-01-01 星期五“这样日期星期混合的,
需要将中文切割出去,并将时间转换成datatimen格式
df1=df.copy()
df1['time']=pd.to_datetime(df['time'].str.split(' ').str.get(0))
df1.sort(columns='time',inplace=True)
df1[:3]
#由于接下来需要用到起始时间,最终时间以及时间间隔,所以对日期进行预处理
#D代表day,s代表秒
startTime=df1.iloc[0,0]
endTime=df1.iloc[-3,0]
delta=(endTime-startTime)/np.timedelta64(1,'D')
month=delta/30
month
6.666666666666667
二、业务指标分析
业务一、月均消费次数
月均消费次数=总消费次数/月份数
def monthConsumeFF(dataframe):
#按照日期及社保账号来清洗数据,将每个人一天的消费次数算作一次消费
mcdif=dataframe.drop_duplicates(['time','cardNum'])
consumeNumber=len(mcdif)
monthConsume=int(consumeNumber/month)
# 月消费次数
print ('月消费次数:',monthConsume)
monthConsumeFF(df1)
月消费次数: 809
#这里结果有些不同,因为7月有19天,如果直接取整数算6个月那计算结果将会有较大偏差,
#所以我觉得平均月份取小数较好
#业务二、月均消费金额
#月均消费金额=总消费金额/月份数
def monthMoneyFF(dataframe):
actualMoneySum=pd.Series.sum(dataframe['actualMoney'])
#print(actualMoneySum
monthMoney=int(actualMoneySum/month)
print (monthMoney)
monthMoneyFF(df1)
45694
#业务三、客单价
#客单价=总消费金额/总消费次数
def ptsF(dataframe):
actualMoneySum=pd.Series.sum(dataframe['actualMoney'])
consumeNumber=len(dataframe.drop_duplicates(['time','cardNum']))
pts=actualMoneySum/consumeNumber
print('客单价:',pts)
ptsF(df1)
客单价: 56.4339125602
#业务四、消费趋势
#消费趋势是按周计算的
import matplotlib.pyplot as plt
#plt.rc('figure', figsize=(12, 10))
import matplotlib.pyplot as pltz
plt.rc('figure', figsize=(12, 5))
np.set_printoptions(precision=4)
def trendF(dataframe):
trend=dataframe.loc[:,['time','actualMoney']]
trend['time']=pd.to_datetime(trend['time'])
trend=trend.set_index('time')
#按周分割并计算周消费总和
s=trend['actualMoney'].resample('W').sum()
trendNew=pd.Series.to_frame(s)
#index format 将年月日改为年周
trendNew.index=trendNew.index.format(formatter=lambda x:x.strftime('%y-%W'))
print (df1)
trendNew.plot()
plt.legend(loc='best')
plt.show()
#业务五、列出各类药品售出数量的排名
plt.rcParams['font.sans-serif']=['SimHel']
plt.rcParams['axes.unicode_minus']=False
def peng(dataframe):
drug=dataframe.loc[:,['drugName','saleNum']]
#按药品名进行归类并计算药品卖出总和
s1=drug.groupby(drug.drugName.str[:])['saleNum'].sum()
drugNew=pd.Series.to_frame(s1)
drugNew=drugNew.sort_values(by='saleNum',ascending=False)
print(df1)
drugNew.plot()
#太拥挤了分成两张图
drugPart1=drugNew.iloc[0:34]
drugPart2=drugNew.iloc[34:,:]
ax1=drugPart1.plot.barh(alpha=0.75,rot=0,fontsize=8)
ax2=drugPart2.plot.barh(alpha=0.75,rot=0,fontsize=8)
ax1.set_xlim(0,2000)
ax2.ser_xlim(0,2000)
print(drugNew)
peng.plot()
peng(df1)
plt.legend(loc='best')
plt.show()
/Users/zhongyaode/anaconda/lib/python3.6/site-packages/matplotlib/font_manager.py:1297: UserWarning: findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans
(prop.get_family(), self.defaultFamily[fontext]))
#业务六、列出每周7天各天各有多少人来医院
def weekday(dataframe):
timeDF=dataframe.drop_duplicates(['time','cardNum'])
timeDF=timeDF.loc[:,['time']]
timeDF['num']=1
timeDF['time']=pd.to_datetime(timeDF['time'])
#将日期换算成周几
timeDF['weekday']=timeDF['time'].dt.dayofweek
weekday=timeDF.loc[:,['weekday','num']]
s2=weekday.groupby('weekday')['num'].sum()
weekdayNew=pd.Series.to_frame(s2)
weekdayNew['weekdays']=['Sunday','Monday','Tuesday','Wednesday','Thurday','Friday','Saturday']
weekdayNew=weekdayNew.set_index('weekdays')
print (weekdayNew)
weekdayNew.plot(kind='bar')
plt.show()
weekday(df1)
num
weekdays
Sunday 703
Monday 796
Tuesday 732
Wednesday 633
Thurday 986
Friday 808
Saturday 740
#可以看出周三来的人最少,周四最多,所以可以据此来分配人手
#简单的数据分析,主要是熟悉pandas的使用并更多的了解数据分析流程,
#接下来进行更加复杂的数据分析学习