<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python數(shù)據(jù)分析案例-藥店銷售數(shù)據(jù)分析

          共 7539字,需瀏覽 16分鐘

           ·

          2021-12-02 10:50

          最近學習了Python數(shù)據(jù)分析的一些基礎知識,就找了一個藥品數(shù)據(jù)分析的小項目來練一下手。

          數(shù)據(jù)分析的目的:

          本篇文章中,假設以朝陽醫(yī)院2018年銷售數(shù)據(jù)為例,目的是了解朝陽醫(yī)院在2018年里的銷售情況,通過對朝陽區(qū)醫(yī)院的藥品銷售數(shù)據(jù)的分析,了解朝陽醫(yī)院的患者的月均消費次數(shù),月均消費金額、客單價以及消費趨勢、需求量前幾位的藥品等。

          數(shù)據(jù)分析基本過程包括:獲取數(shù)據(jù)、數(shù)據(jù)清洗、構建模型、數(shù)據(jù)可視化以及消費趨勢分析。

          數(shù)據(jù)準備

          數(shù)據(jù)是存在Excel中的,可以使用pandas的Excel文件讀取函數(shù)將數(shù)據(jù)讀取到內(nèi)存中,這里需要注意的是文件名和Excel中的sheet頁的名字。讀取完數(shù)據(jù)后可以對數(shù)據(jù)進行預覽和查看一些基本信息。

          獲取數(shù)據(jù):https://pan.baidu.com/share/init?surl=tKaERGWFPycqTC1cElvc9A

          提取碼: 6xm2

          導入原始數(shù)據(jù)

          import numpy as np
          from pandas import Series,DataFrame
          import pandas as pd
          #導入數(shù)據(jù)
          file_name = '朝陽醫(yī)院2018年銷售數(shù)據(jù).xlsx'
          # 使用ExcelFile()時需要傳入目標excel文件所在路徑及文件名稱
          xls = pd.ExcelFile(file_name)
          # 使用parse()可以根據(jù)傳入的sheet名稱來提取對應的表格信息
          dataDF = xls.parse('Sheet1',dtype='object')
          # 輸出前五行數(shù)據(jù)
          dataDF.head()

          # 使用sheet_names來查看當前表格中包含的所有sheet名稱(按順序)
          print(xls.sheet_names[0])

          查看數(shù)據(jù)基本信息:

          #查看基本信息
          #查看數(shù)據(jù)幾行幾列
          print(dataDF.shape)
          #查看索引
          print(dataDF.index)
          #查看每一列的列表頭內(nèi)容
          print(dataDF.columns)
          #查看每一列數(shù)據(jù)統(tǒng)計數(shù)目
          print(dataDF.count())

          數(shù)據(jù)清洗

          數(shù)據(jù)清洗過程包括:選擇子集、列名重命名、缺失數(shù)據(jù)處理、數(shù)據(jù)類型轉換、數(shù)據(jù)排序及異常值處理

          (1)選擇子集

          在我們獲取到的數(shù)據(jù)中,可能數(shù)據(jù)量非常龐大,并不是每一列都有價值都需要分析,這時候就需要從整個數(shù)據(jù)中選取合適的子集進行分析,這樣能從數(shù)據(jù)中獲取最大價值。在本次案例中不需要選取子集,暫時可以忽略這一步。

          (2)列重命名

          在數(shù)據(jù)分析過程中,有些列名和數(shù)據(jù)容易混淆或產(chǎn)生歧義,不利于數(shù)據(jù)分析,這時候需要把列名換成容易理解的名稱,可以采用rename函數(shù)實現(xiàn):

          #列重命名
          dataDF.rename(columns={<!-- -->'購藥時間':'銷售時間'},inplace=True)
          dataDF.head()

          (3)缺失值處理

          獲取的數(shù)據(jù)中很有可能存在缺失值,通過查看基本信息可以推測“購藥時間”和“社??ㄌ枴边@兩列存在缺失值,如果不處理這些缺失值會干擾后面的數(shù)據(jù)分析結果。 缺失數(shù)據(jù)常用的處理方式為刪除含有缺失數(shù)據(jù)的記錄或者利用算法去補全缺失數(shù)據(jù)。 在本次案例中為求方便,直接使用dropna函數(shù)刪除缺失數(shù)據(jù),具體如下:

          #缺失值處理
          print('刪除缺失值前:', dataDF.shape)

          # 使用info查看數(shù)據(jù)信息,
          print(dataDF.info())
          #刪除缺失值
          dataDF = dataDF.dropna(subset=['銷售時間','社??ㄌ?], how='any')
          print('\n刪除缺失值后',dataDF.shape)
          print(dataDF.info())

          (4)數(shù)據(jù)類型轉換

          在導入數(shù)據(jù)時為了防止導入不進來,會強制所有數(shù)據(jù)都是object類型,但實際數(shù)據(jù)分析過程中“銷售數(shù)量”,“應收金額”,“實收金額”,這些列需要浮點型(float)數(shù)據(jù),“銷售時間”需要改成時間格式,因此需要對數(shù)據(jù)類型進行轉換。 可以使用astype()函數(shù)轉為浮點型數(shù)據(jù):

          #數(shù)據(jù)類型轉換
          dataDF['銷售數(shù)量'] = dataDF['銷售數(shù)量'].astype('float')
          dataDF['應收金額'] = dataDF['應收金額'].astype('float')
          dataDF['實收金額'] = dataDF['實收金額'].astype('float')
          print(dataDF.dtypes)

          在“銷售時間”這一列數(shù)據(jù)中存在星期這樣的數(shù)據(jù),但在數(shù)據(jù)分析過程中不需要用到,因此要把銷售時間列中日期和星期使用split函數(shù)進行分割,分割后的時間,返回的是Series數(shù)據(jù)類型:

          '''
          定義函數(shù):分割銷售日期,提取銷售日期
          輸入:timeColSer 銷售時間這一列,Series數(shù)據(jù)類型,例‘2018-01-01 星期五’
          輸出:分割后的時間,返回Series數(shù)據(jù)類型,例‘2018-01-01’
          '
          ''
          def splitSaletime(timeColSer):
              timeList=[]
              
              for value in timeColSer:
                  dateStr=value.split(' ')[0] #用空格進行分割
                  timeList.append(dateStr)

              timeSer=pd.Series(timeList)    #將列表轉行為一維數(shù)據(jù)Series類型
              return timeSer

          #獲取“銷售時間”這一列
          timeSer = dataDF.loc[:,'銷售時間']

          #對字符串進行分割,提取銷售日期
          dateSer = splitSaletime(timeSer)

          #修改銷售時間這一列的值
          dataDF.loc[:,'銷售時間'] = dateSer
          dataDF.head()

          '''
          數(shù)據(jù)類型轉換:字符串轉換為日期

          把切割后的日期轉為時間格式,方便后面的數(shù)據(jù)統(tǒng)計:
          '
          ''
          #errors='coerce' 如果原始數(shù)據(jù)不符合日期的格式,轉換后的值為空值NaT
          dataDF.loc[:,'銷售時間']=pd.to_datetime(dataDF.loc[:,'銷售時間'],format='%Y-%m-%d', errors='coerce')

          print(dataDF.dtypes)


          dataDF.isnull().sum()


          '''
          轉換日期過程中不符合日期格式的數(shù)值會被轉換為空值
          刪除含有NaT的空行
          '
          ''
          dataDF = dataDF.dropna(subset=['銷售時間','社??ㄌ?],how='any')
          datasDF = dataDF.reset_index(drop = True)
          dataDF.info()


          (5)數(shù)據(jù)排序

          此時時間是沒有按順序排列的,所以還是需要排序一下,排序之后索引會被打亂,所以也需要重置一下索引。 其中by:表示按哪一列進行排序,ascending=True表示升序排列,ascending=False表示降序排列

          #數(shù)據(jù)排序
          dataDF = dataDF.sort_values(by='銷售時間', ascending=True)
          dataDF = dataDF.reset_index(drop=True)
          dataDF.head()


          (6)異常值處理

          先查看數(shù)據(jù)的描述統(tǒng)計信息

          #查看描述統(tǒng)計信息
          dataDF.describe()


          通過描述統(tǒng)計信息可以看到,“銷售數(shù)量”、“應收金額”、“實收金額”這三列數(shù)據(jù)的最小值出現(xiàn)了負數(shù),這明顯不符合常理,數(shù)據(jù)中存在異常值的干擾,因此要對數(shù)據(jù)進一步處理,以排除異常值的影響:

          #將'銷售數(shù)量'這一列小于0的數(shù)據(jù)排除掉
          pop = dataDF.loc[:,'銷售數(shù)量'] &gt; 0
          dataDF = dataDF.loc[pop,:]
          dataDF.describe()


          構建模型及數(shù)據(jù)可視化

          數(shù)據(jù)清洗完成后,需要利用數(shù)據(jù)構建模型(就是計算相應的業(yè)務指標),并用可視化的方式呈現(xiàn)結果。

          (1)業(yè)務指標1:月均消費次數(shù)

          月均消費次數(shù) = 總消費次數(shù) / 月份數(shù)(同一天內(nèi),同一個人所有消費算作一次消費)

          #計算總消費次數(shù)
          #刪除重復數(shù)據(jù)
          kpil_Df = dataDF.drop_duplicates(subset=['銷售時間','社??ㄌ?])
          totalI = kpil_Df.shape[0]
          print('總消費次數(shù)=',totalI)

          #計算月份數(shù)
          #按銷售時間升序排序
          kpil_Df = kpil_Df.sort_values(by='銷售時間', ascending=True)
          #重命名行名
          kpil_Df = kpil_Df.reset_index(drop=True)
          #獲取時間范圍
          startTime = kpil_Df.loc[0,'銷售時間']
          endTime = kpil_Df.loc[totalI-1,'銷售時間']
          #計算月份
          #天數(shù)
          daysI = (endTime-startTime).days
          mounthI = daysI//30
          print('月份數(shù)=',mounthI)

          #月平均消費次數(shù)
          kpil_I = totalI//mounthI
          print('業(yè)務指標1:月均消費次數(shù)=', kpil_I)


          (2)業(yè)務指標2:月均消費金額

          月均消費金額 = 總消費金額 / 月份數(shù)

          #消費總金額
          totalMoneyF = dataDF.loc[:,'實收金額'].sum()
          mounthMoney = totalMoneyF // mounthI
          print('業(yè)務指標2:月均消費金額=', mounthMoney)


          (3)客單價

          客單價 = 總消費金額 / 總消費次數(shù)

          #客單價
          pct = totalMoneyF / totalI
          print('業(yè)務指標3:客單價=', pct)


          (4)消費趨勢

          a. 導入python可視化相關的包

          b. 分析每天的消費金額

          import matplotlib.pyplot as plt
          import matplotlib
          #畫圖時用于顯示中文字符
          from pylab import mpl

          mpl.rcParams['font.sans-serif'] = ['SimHei'# SimHei是黑體的意思
          #在操作之前先復制一份
          #mpl.rcParams['font.sans-serif'] = ['Songti'] # SimHei是黑體的意思
          #font = FontProperties(fname='/Library/Fonts/Songti.ttc') #設置字體
          #在操作之前先復制一份數(shù)據(jù),防止影響清洗后的數(shù)據(jù)
          groupDF = dataDF

          #將'銷售時間'設置為index
          groupDF.index = groupDF['銷售時間']
          print(groupDF.head())
          gb = groupDF.groupby(groupDF.index)
          print(gb)
          dayDF = gb.sum()
          print(dayDF)
          #畫圖
          plt.plot(dayDF['實收金額'])
          plt.title('按天消費金額')
          plt.xlabel('時間')
          plt.ylabel('實收金額')
          plt.show()


          從結果可以看出,每天消費總額差異較大,除了個別天出現(xiàn)比較大筆的消費,大部分人消費情況維持在1000-2000元以內(nèi)。

          c. 分析每月的消費金額

          接下來,我銷售時間先聚合再按月分組進行分析:

          #將銷售時間聚合按月分組
          gb = groupDF.groupby(groupDF.index.month)
          print(gb)
          monthDF = gb.sum()
          print(monthDF)

          plt.plot(monthDF['實收金額'])
          plt.title('按月消費金額')
          plt.xlabel('時間')
          plt.ylabel('實收金額')
          plt.show()


          結果顯示,7月消費金額最少,這是因為7月份的數(shù)據(jù)不完整,所以不具參考價值。1月、4月、5月和6月的月消費金額差異不大.  2月和3月的消費金額迅速降低,這可能是2月和3月處于春節(jié)期間,大部分人都回家過年的原因。

          d. 分析藥品銷售情況

          對“商品名稱”和“銷售數(shù)量”這兩列數(shù)據(jù)進行聚合為Series形式,方便后面統(tǒng)計,并按降序排序:

          #聚合統(tǒng)計各種藥品數(shù)量
          medicine = groupDF[['商品名稱','銷售數(shù)量']]
          bk = medicine.groupby('商品名稱')[['銷售數(shù)量']]
          re_medicine = bk.sum()

          #對銷售藥品數(shù)量按將序排序
          re_medicine = re_medicine.sort_values(by='銷售數(shù)量', ascending=False)
          re_medicine.head()


          截取銷售數(shù)量最多的前十種藥品,并用條形圖展示結果:

          top_medicine = re_medicine.iloc[:10,:]
          top_medicine

          # 數(shù)據(jù)可視化,用條形圖展示前十的藥品
          top_medicine.plot(kind = 'bar')
          plt.title('銷售前十的藥品')
          plt.xlabel('藥品')
          plt.ylabel('數(shù)量')
          plt.show()


          結論:對于銷售量排在前幾位的藥品,醫(yī)院應該時刻關注,保證藥品不會短缺而影響患者。得到銷售數(shù)量最多的前十種藥品的信息,這些信息也會有助于加強醫(yī)院對藥房的管理。

          e. 每天的消費金額分布情況

          每天的消費金額分布情況:一橫軸為時間,縱軸為實收金額畫散點圖。

          # 每天消售金額 -- 散點圖
          plt.scatter(dataDF['銷售時間'],dataDF['實收金額'])
          plt.title('每天銷售金額')
          plt.xlabel('時間')
          plt.ylabel('實收金額')
          plt.show()


          結論:從散點圖可以看出,每天消費金額在500以下的占絕大多數(shù),個別天存在消費金額很大的情況。

          參考文章:https://www.jianshu.com/p/1becc1e5dbea




          Python“寶藏級”公眾號【Python之王】專注于Python領域,會爬蟲,數(shù)分,C++,tensorflow和Pytorch等等。

          近 2年共原創(chuàng) 100+ 篇技術文章。創(chuàng)作的精品文章系列有:

          日常收集整理了一批不錯的 Python 學習資料,有需要的小伙可以自行免費領取。

          獲取方式如下:公眾號回復資料。領取Python等系列筆記,項目,書籍,直接套上模板就可以用了。資料包含算法、python、算法小抄、力扣刷題手冊和 C++ 等學習資料!


          瀏覽 73
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费无码一级A片大黄在线观看 | 黄色视频网站日本 | 国产AV毛片 | 蜜桃 入口 | 人人爱人人摸视频 |