數據分析實例——醫院銷售數據分析
1 序言
數據分析的基本步驟是:提出問題——理解數據——數據清洗——構建模型——數據可視化。本文基於Python中的Pandas包,對某醫院銷售數據進行分析。 2 分析目的根據原始銷售數據,分析月均消費次數、月均消費金額、客單價、消費趨勢4個業務指標。
3 理解數據 首先導入銷售數據表:# 導入pandas包,從文件讀取Excel數據import pandas as pdfileNameStr=./朝陽醫院2018年銷售數據.xlsxxls = pd.ExcelFile(fileNameStr, dtype=object)salesDf = xls.parse(Sheet1,dtype=object)# 查看數據基本信息salesDf.head()
# 查看數據集大小salesDf.shape(6578, 7)# 查看數據類型salesDf.dtypes購葯時間 object社保卡號 object商品編碼 object商品名稱 object銷售數量 object應收金額 object實收金額 objectdtype: object
4 數據清洗
數據清洗的一般步驟包括:選擇子集—列名重命名—缺失數據處理—數據類型轉換—數據排序—異常值處理。下面將通過此例逐步實踐上述過程。 1) 選擇子集 本案例數據集能夠滿足分析要求,不需要選擇子集。 2) 列名重命名#創建舊列名和新列名對應關係,並在原數據框中進行重命名colNameDict = {購葯時間:銷售時間}salesDf.rename(columns = colNameDict,inplace=True)salesDf.head()
3) 缺失數據處理
pandas使用浮點值NaN表示浮點和非浮點數組裡的缺失數據,可以用isnull()和notnull()函數來判斷缺失情況。 對於缺失數據的一般處理方法是刪除或者填充。本例對缺失數據進行刪除處理。print(刪除缺失值前大小,salesDf.shape)刪除缺失值前大小 (6578, 7)# 刪除列(銷售時間,社保卡號)中為空的行salesDf=salesDf.dropna(subset=[銷售時間,社保卡號],how=any)print(刪除缺失後大小,salesDf.shape)刪除缺失後大小 (6575, 7)
4) 數據類型轉換
讀取數據時是按照字元串格式讀取的,需要將數據列從字元串格式轉換為數值型。
#字元串轉換為數值(浮點型)salesDf[銷售數量] = salesDf[銷售數量].astype(float)salesDf[應收金額] = salesDf[應收金額].astype(float)salesDf[實收金額] = salesDf[實收金額].astype(float)print(轉換後的數據類型:
,salesDf.dtypes)轉換後的數據類型: 銷售時間 object社保卡號 object商品編碼 object商品名稱 object銷售數量 float64應收金額 float64實收金額 float64dtype: object
數據集中,銷售時間的格式為「2018-01-01 星期五」,分析中並不需要星期信息,因此需通過字元串分割,將其刪除,只保留日期「2018-01-01」。
def splitSaletime(timeColSer): timeList=[] for value in timeColSer: #例如2018-01-01 星期五,分割後為:2018-01-01 dateStr=value.split( )[0] timeList.append(dateStr) #將列錶轉行為一維數據Series類型 timeSer=pd.Series(timeList) return timeSer#獲取「銷售時間」列timeSer=salesDf.loc[:,銷售時間]#對字元串進行分割,獲取銷售日期dateSer=splitSaletime(timeSer)#修改銷售時間這一列的值salesDf.loc[:,銷售時間]=dateSersalesDf.head()
# 將「銷售時間」轉換為日期格式# format 是原始數據中日期的格式salesDf.loc[:,銷售時間]=pd.to_datetime(salesDf.loc[:,銷售時間], format=%Y-%m-%d, errors=coerce)salesDf.dtypes銷售時間 datetime64[ns]社保卡號 object商品編碼 object商品名稱 object銷售數量 float64應收金額 float64實收金額 float64dtype: object# 轉換後出現空行,將其刪除salesDf=salesDf.dropna(subset=[銷售時間,社保卡號],how=any)
5) 數據排序
# 按銷售日期進行升序排列salesDf=salesDf.sort_values(by=銷售時間, ascending=True)salesDf.head()
#重命名行名(index):排序後的列索引值是之前的行號,需要修改成從0到N按順序的索引值salesDf=salesDf.reset_index(drop=True)salesDf.head()
6) 異常值處理
# 查看數據統計信息,「銷售數量」值不能小於0salesDf.describe()
# 刪除異常值:通過條件判斷篩選出數據# 查詢條件querySer=salesDf.loc[:,銷售數量]>0# 應用查詢條件salesDf=salesDf.loc[querySer,:]
4 構建模型
1) 業務指標1:月均消費次數=總消費次數 / 月份數# 同一天、同一個社保卡號視為一次消費,因此需刪除重複記錄kpi1_Df=salesDf.drop_duplicates( subset=[銷售時間, 社保卡號])# 總消費次數:有多少行totalI=kpi1_Df.shape[0]print(總消費次數=,totalI)總消費次數= 5342# 計算月份數# 按銷售時間升序排序kpi1_Df=kpi1_Df.sort_values(by=銷售時間, ascending=True)# 重命名行名(index)kpi1_Df=kpi1_Df.reset_index(drop=True)# 獲取時間範圍startTime=kpi1_Df.loc[0,銷售時間]endTime=kpi1_Df.loc[totalI-1,銷售時間]#天數daysI=(endTime-startTime).days#月份數monthsI=daysI//30print(月份數:,monthsI)月份數: 6#業務指標1:月均消費次數=總消費次數 / 月份數kpi1_I=totalI // monthsIprint(業務指標1:月均消費次數=,kpi1_I)業務指標1:月均消費次數= 890
2) 業務指標2:月均消費金額 = 總消費金額 / 月份數
#總消費金額totalMoneyF=salesDf.loc[:,實收金額].sum()#月均消費金額monthMoneyF=totalMoneyF / monthsIprint(業務指標2:月均消費金額=,monthMoneyF)業務指標2:月均消費金額= 50668.35166666666
3) 業務指標3:客單價 = 總消費金額 / 總消費次數
pct=totalMoneyF / totalIprint(客單價:,pct)客單價: 56.909417821040805
4) 業務指標4:消費趨勢
# 數據分組groupDf=salesDf# 重命名行名(index)為銷售時間所在列的值groupDf.index=groupDf[銷售時間]gb=groupDf.groupby(groupDf.index.month)monthDf=gb.sum()monthDf
import matplotlib.pyplot as pltx = monthDf.loc[:,銷售數量]xplt.plot(x,marker=o,markerfacecolor=blue, markersize=8)plt.title(Trend of change in sales volume)plt.xlabel(Months)plt.ylabel(sales volume)plt.show()
y = monthDf.loc[:,實收金額]yplt.plot(y,marker=o,markerfacecolor=blue, markersize=8)plt.title(Trend of change in sales amount)plt.xlabel(Months)plt.ylabel(sales amount)plt.show()
推薦閱讀:
※知乎Live數據面面觀
※紙上得來終覺淺 絕知此事要躬行
※世界排名500強網站流量一覽
※數據之美
※手機報表用處多,這些場景值得收藏!
TAG:數據分析 |