利用Python進行簡單數據分析--醫院銷售數據分析案例

本案例數據集地址(百度網盤):鏈接:https://pan.baidu.com/s/1FsEcr3lanXYbYLxGELtJZw 提取碼:5nvw (此鏈接永久有效)

或掃描下方二維碼獲取:

在本次博客中,我將利用Python數據分析工具來做一個某醫院某年度的銷售情況彙總。

項目運行環境:

操作系統 Windows 10 64位
Python 3.7.0
開發工具 Pycharm(ipython)

數據分析的基本過程主要分爲兩方面:

一、數據分析的目的

  一方面是發現問題,並且找到問題的根源,最終通過切實可行的辦法解決存在的問題;另一方面,提取有用信息和形成結論而對數據加以詳細研究和概括,對以往的數據分析,總結髮展趨勢,爲網絡營銷決策提供支持。

二 、數據分析基本過程

  數據分析基本過程包括:獲取數據、數據清洗、構建模型、數據可視化、得出結論。

1.獲取數據

注:本次項目使用的數據請在前面鏈接自行下載
導包

import os
import pandas as pd
import matplotlib.pyplot as plt
設置工作路徑
os.chdir(r'填寫你的數據所在路徑') #比如:os.chdir(r'F:\360Downloads\朝陽醫院')
讀取數據
dataDF=pd.read_ecxel('文件名(記得帶文件後綴名)') #比如:dataDF=pd.read_excel('朝陽醫院2018年銷售數據.xlsx')
查看前5行數據
dataDF.head() #默認查看前5行


接下來查看數據的下列信息:shape(形狀)、index(索引)、columns(列名)、count(總數)

dataDF.shape #查看數據的結構(行、列數)

dataDF.index #查看數據的索引

dataDF.columns #查看數據的列名

dataDF.count() #查看數據的總數

dataDF.describe() #查看數據的數值詳細信息

  通過以上的數據可以看出:
總共有6578行7列數據,但是“購藥時間”和“社保卡號”這兩列只有6576個數據,而“商品編碼”一直到“實收金額”這些列都是隻有6577個數據。這就意味着數據中存在缺失值,可以推斷出數據中存在一行缺失值。
此外“購藥時間”和“社保卡號”這兩列都各自存在一個缺失數據,這些缺失數據在後面步驟中需要進一步處理。
而且數據中存在負數,這將在後面也需要進一步處理。

2.數據清洗

數據清洗通常包括:選擇子集、修改列名稱、處理缺失值、處理異常值、轉換數據類型、數據排序(爲可視化做準備),在這裏我們根據實驗數據本身特徵進行處理,過程如下:


選擇子集:

在進行數據分析時,通常會遇到非常龐大的數據包,並且其中難免會有一些‘無用’的數據,以及和本次項目不相關的信息,這時就需要將其分開並按照需求選擇,得到有價值的數據集來進行進一步分析,從而挖掘出我們需要的潛在信息。由於本次案例使用的數據集量小且簡單,因此可以忽略這一步。

修改列名稱:

在拿到的原始數據中,列名稱和數據和其他列名之間可能會相似或者不能夠‘見名知意’,導致給後續分析帶來困難,爲了避免此現象,我們可以根據需求調用rename()函數將列名重命名,比如中文名稱(這裏純屬個人習慣)
dataDF=dataDF.rename(columns={'購藥時間':'銷售時間'})
dataDF.head()

處理缺失值:

通過上面的dataDF.count()可以看出,數據的“購藥時間”和“社保卡號”行數和其他數據不相等,證明肯定存在空值,爲了不對後續的操作造成干擾,在這裏需要進一步處理,通常處理方式有兩種:第一,刪除;第二,填充。在本次案例中,由於數據簡單,我們採用第一種方式將含有空值的行刪除,得到‘乾淨’數據,使用到的函數有dropna()
dataDF=dataDF.dropna(subset=['銷售時間','社保卡號'],how='any')
dataDF.count()

處理異常值:

我們先來查看一下數據的當前信息:

dataDF.describe()


可以看出數據當中存在異常值(負值)。

現在我們刪除負值所在的行

pop=dataDF.loc[:,'銷售數量']>0

dataDF=dataDF.loc[pop,:]
dataDF.describe()
如下圖所示(負值)已經刪除

接下來再查看一下數據信息(行數)

轉換數據類型:

我們先來查看一下數據的當前類型:

發現銷售時間這一列並不是我們想要的datetime格式,因此需要轉換,爲後續分析做準備。這裏使用到的函數有:astype()函數

在處理之前,原始數據如下圖(發現‘銷售時間’這一列存在星期*,顯然這並不是我們需要的,接下來我們編寫(分割)函數將其去除,具體操作如下):

下圖是我編寫的一個(分割)函數以及具體操作(此處方法很多,遠遠不止這一種)

本案例操作方法如下:

調用函數,處理數據(具體過程見上圖的‘函數調用方法’部分)

time=dataDF.loc[:,'銷售時間']
data=SplitSaletime(time)
dataDF.loc[:,'銷售時間']=data

處理後的數據(銷售時間)如下:

查看當前數據類型(如下圖,發現銷售時間列格式已經修改成功,接下來將其轉換爲datetime類型即可):

dataDF.loc[:,'銷售時間']=pd.to_datetime(dataDF.loc[:,'銷售時間'],format='%Y-%m-%d',errors='coerce')

此時我們再來看數據(銷售時間)類型,發現已經轉換成功:

數據排序(重置索引):

接下來我們按照時間列進行升序排序

dataDF=dataDF.sort_values(by=['銷售時間'],ascending=True) #by='填寫需要按照那一列來排序',ascending=True表示升序(False表示降序)

然後重置索引

dataDF=dataDF.reset_index(drop=True)

3.構建模型

數據準備就緒後,根據相關業務利用可視化工具實現圖標製作,從而挖掘出數據背後的信息。

需求一:月均消費次數(月均消費次數 = 總消費次數/月份數)

第一步:計算總消費次數(爲了便於統計,每張社保卡在當天的所有消費記錄當做一次消費,因此首先需要對數據進行‘去重’操作,這裏需要用到drop_duplicates()函數)

dataDF_qc=dataDF.drop_duplicates(subset=['銷售時間','社保卡號'])

接着查看數據形狀,看是否有變化:

再看一下原始數據形狀:

打印重複的行數:

print(f'原始數據與去重後的數據行數相差:{dataDF.shape[0]-dataDF_qc.shape[0]}行。')

計算總消費次數:

Total_time=dataDF_qc.shape[0]

結果如下:

第二步:計算月份數

按照銷售時間升序排序,然後重置索引

升序排序dataDF_shengxu=dataDF_qc.sort_values(by=['銷售時間'],ascending=True)
重置索引dataDF_qc_resrt_index=dataDF_qc.reset_index(drop=True)
現在來查看數據索引
索引:

計算銷售時間範圍:

StartTime=dataDF_qc_resrt_index.loc[0,'銷售時間']
EndTime=dataDF_qc_resrt_index.loc[Total_time-1,'銷售時間']

此時發現銷售時間出現空值,因此這裏我們刪除空值所在行數據:

dataDF_qc_resrt_index.dropna(subset=['銷售時間'],inplace=True)
然後查看數據行數信息(如下圖,發現再沒有空值):

現在我們重複上述步驟獲取開始和結束時間:

StartTime=dataDF_qc_resrt_index.loc[0,'銷售時間']
EndTime=dataDF_qc_resrt_index.loc[Total_time-1,'銷售時間']

計算總天數:

Day_time=(EndTime-StartTime).days

計算月份數:

Month_time=Day_time//30 #其中//爲整除運算,每月按30天計

月均消費次數 = 總消費次數/月份數:

Ave_time=Total_time//Month_time

需求二:月均消費金額(月均消費次數 = 總消費金額/月份數)

第一步:計算總消費金額(這裏用到sum()函數求和)

Total_Money=data_new.loc[:,'實收金額'].sum()

第二步:計算月均消費金額

print(f'每月平均消費{(Total_Money//Month_time)}元。')

需求三:每次購藥平均消費金額(每次購藥平均消費金額 = 總消費金額/總購藥次數)

print(f'每次購藥平均消費金額爲:{(Total_Money/Total_time)}元。')

4.數據可視化

準備工作:

導入可視化包:
import matplotlib.pyplot as plt
遇到數據中有中文的時候,一定要先設置中文字體
plt.rcParams['font.sans-serif']=['SimHei'] # 用黑體顯示中文

首先將數據複製到一個新的變量,專門用作數據可視化

Data_KSH=dataDF_qc_resrt_index

需求一:查看每日消費金額

重置索引爲‘銷售時間’列:

Data_KSH.index=Data_KSH['銷售時間']

繪製圖形:

總結:日均 消費金額大部分集中在500元左右,並且上下波動不大。

需求二:查看每月銷售金額

數據聚合(按照月份):

Mon=Data_KSH.groupby(Data_KSH.index.month)

利用sum()求和,計算每月銷售金額:

Mon_Money=Mon.sum()

繪製圖形:

總結:如圖所示:3、4、5、6月份銷售數據相對平穩均在4500元左右,其他月份波動較大。

需求三:查看銷售量前十的藥品

按照銷售數量排序:

Data_XSSL=Data_KSH.sort_values(by='銷售數量')

按照銷售數量去重:

Data_XSSL=Data_XSSL.drop_duplicates(subset=['銷售數量'])

提取前十行數據:

Top_10=Data_XSSL.iloc[:10,:]

查看前十行數據:

繪製圖形:

總結:銷售量前十的藥品如圖所示。

三、附件:本案例源代碼

本案例數據集地址(百度網盤):鏈接:https://pan.baidu.com/s/1mStg3VcubipPx3EzQwMLEQ 提取碼:5ua5 (此鏈接永久有效)

或者掃描下方二維碼獲取源代碼:

看完記得點贊收藏哈~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章