Python數據分析流程(以藥店銷售數據為例)

Python數據分析流程(以藥店銷售數據為例)

一、一維數據分析

#導入numpy包和pandas包import numpy as npimport pandas as pd

1.1 numpy一維數據結構:array

#定義一個一維數組,參數傳入的是一個列表a=np.array([2,3,4,5])#查詢:方括弧a[0]#切片訪問:獲取指定序號範圍的元素a[1:3]#查看數據類型a.dtype#描述統計#平均值a.mean()#標準差a.std()

#向量化運行:乘以標量b=np.array([1,2,3])c=b*4

1.2 pandas一維數據結構:Series

#pandas一維數據結構Series:用pd.Series()定義數組,用index()定義索引#存放六家公司某日的股價stockS=pd.Series([54.74,190.9,173.14,1050.3,181.86,1139.49], index=[騰訊, 阿里巴巴, 蘋果, 谷歌, Facebook, 亞馬遜])

stock騰訊 54.74阿里巴巴 190.90蘋果 173.14谷歌 1050.30Facebook 181.86亞馬遜 1139.49dtype: float64

stockS.describe()count 6.000000mean 465.071667std 491.183757min 54.74000025% 175.32000050% 186.38000075% 835.450000max 1139.490000dtype: float64

#iloc屬性用於根據索引獲取值stockS.iloc[0]#loc屬性用於根據索引獲取值stockS.loc[騰訊]#向量化運算:向量相加s1=pd.Series([1,2,3,4],index=[a,b,c,d])s2=pd.Series([10,20,30,40],index=[a,b,e,f])s3=s1+s2

s3a 11.0b 22.0c NaNd NaNe NaNf NaNdtype: float64

#缺失值處理#方法1:刪除缺失值s3.dropna()a 11.0b 22.0dtype: float64

#方法2:將缺失值進行填充s3=s1.add(s2,fill_value=0)s3a 11.0b 22.0c 3.0d 4.0e 30.0f 40.0dtype: float64

二、二維數據分析

2.1 numpy二維數組:array

#用numpy定義二維數組:np.array()a=np.array([ [1,2,3,4], [5,6,7,8], [9,10,11,12]])

#獲取行號是0,列號是2的元素a[0,2]#獲取第一列a[:,0]#獲取第一行a[0,:]

#numpy數軸參數:axis#如果沒有指定數軸參數,會計算整個數組的相應值a.mean()#按軸計算:axis=1按行計算,axis=0按列計算a.mean(axis=1)

array([ 2.5, 6.5, 10.5])

2.2 pandas二維數組:數據框DataFrames

#定義一個字典,映射列名與對應列的值salesDict={ 購葯時間:[2018-01-01 星期五,2018-01-02 星期六,2018-01-06 星期三], 社保卡號:[001616528,001616528,0012602828], 商品編碼:[236701,236701,236701], 商品名稱:[強力VC銀翹片,清熱解毒口服液,感康], 銷售數量:[6,1,2], 應收金額:[82.8,28,16.8], 實收金額:[69,24.64,15]}#導入有序字典from collections import OrderedDict#定義一個有序字典salesOrderDict=OrderedDict(salesDict)#定義數據框:傳入字典、列名salesDf=pd.DataFrame(salesOrderDict)

salesDf#平均值:是按照列來求平均值salesDf.mean()

商品編碼 236701.000000銷售數量 3.000000應收金額 42.533333實收金額 36.213333dtype: float64

2.3 pandas中的數據查詢:根據位置獲取值iloc[],根據索引獲取值loc[]

salesDf.iloc[0,1]

001616528

#獲取第一行所有列的數據salesDf.iloc[0,:]

購葯時間 2018-01-01 星期五社保卡號 001616528商品編碼 236701商品名稱 強力VC銀翹片銷售數量 6應收金額 82.8實收金額 69Name: 0, dtype: object

#獲取第一列所有行的數據salesDf.iloc[:,0]

0 2018-01-01 星期五1 2018-01-02 星期六2 2018-01-06 星期三Name: 購葯時間, dtype: object

#loc[]用於根據索引獲取值#獲取第一行salesDf.loc[0,:]

購葯時間 2018-01-01 星期五社保卡號 001616528商品編碼 236701商品名稱 強力VC銀翹片銷售數量 6應收金額 82.8實收金額 69Name: 0, dtype: object

#獲取第一行第一列的元素salesDf.loc[:,購葯時間]

0 2018-01-01 星期五1 2018-01-02 星期六2 2018-01-06 星期三Name: 購葯時間, dtype: object

#簡單方法:獲取「商品名稱」這一列salesDf[商品名稱]

0 強力VC銀翹片1 清熱解毒口服液2 感康Name: 商品名稱, dtype: object

2.4.1 數據框複雜查詢:切片功能

#通過列表來選擇某幾列數據salesDf[[商品名稱,銷售數量]]

#通過切片功能,獲取指定範圍的salesDf.loc[:,購葯時間:銷售數量]

2.4.2 數據框複雜查詢:條件判斷

#通過條件判斷篩選#第一步:構建查詢條件querySer=salesDf.loc[:,銷售數量]>1type(querySer)

pandas.core.series.Series

querySer0 True1 False2 TrueName: 銷售數量, dtype: bool

2.5 查看數據集描述統計信息

#讀取Excel數據fileNameStr=./朝陽醫院2018年銷售數據.xlsxxls=pd.ExcelFile(fileNameStr)salesDf=xls.parse(Sheet1)#列印前三行salesDf.head(3)

#有多少行,多少列salesDf.shape

#查看每一列的數據類型salesDf.loc[:,銷售數量].dtype

#查看每一列的統計數值salesDf.describe()

三、藥店銷售數據分析

3.1 提出問題

從銷售數據中分析以下業務指標:1)月均消費次數 2)月均消費金額 3)客單價 4)消費趨勢

#讀取Excel數據,統一先按照字元串讀入,之後轉換fileNameStr=./朝陽醫院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

3.2 數據清洗

1)選擇子集

如:subSalesDf=salesDf.loc[0:4,購葯時間:銷售數量]

2) 列名重命名

#字典:舊列名和新列名對應關係colNameDict={購葯時間:銷售時間}inplace=False,數據框本身不會變,而會創建一個改動後新的數據框,默認的inplace是Falseinplace=True,數據框本身會改動salesDf.rename(columns=colNameDict)

salesDf.rename(columns=colNameDict,inplace=True)salesDf.head()

3.3 缺失值處理

print(刪除缺失值前大小,salesDf.shape)

刪除缺失值前大小 (6578, 7)

#刪除列(銷售時間,社保卡號)中為空的行#how=any 在給定的任何一列中有缺失值就刪除salesDf=salesDf.dropna(subset=[銷售時間,社保卡號],how=any)

print(刪除缺失後大小,salesDf.shape)

刪除缺失後大小 (6575, 7)

3.4 數據類型轉換

#字元串轉換為數值(浮點型)salesDf[銷售數量] = salesDf[銷售數量].astype(float)salesDf[應收金額] = salesDf[應收金額].astype(float)salesDf[實收金額] = salesDf[實收金額].astype(float)print(轉換後的數據類型:
,salesDf.dtypes)

轉換後的數據類型: 銷售時間 object社保卡號 object商品編碼 object商品名稱 object銷售數量 float64應收金額 float64實收金額 float64dtype: object

#測試:字元串分割testList=2018-06-03 星期五.split( )

testList

[2018-06-03, 星期五]

testList[0]

2018-06-03

定義函數:分割銷售日期,獲取銷售時間輸入:timeColSer 銷售時間這一列是Series數據類型輸出:分割後的時間,返回也是Series數據類型def SplitSaletime(timeColSer): timeList=[] for value in timeColSer: #分割後取第一個元素(年月日) dateStr=value.split( )[0] timeList.append(dateStr) #將列錶轉行為一維數據Series類型 timeSer=pd.Series(timeList) return timeSer

#獲取「銷售時間」這一列timeSer=salesDf.loc[:,銷售時間]#對字元串進行分割,獲取銷售時間dateSer=SplitSaletime(timeSer)

是因為Excel中的空的cell讀入pandas中是空值(NaN),這個NaN是個浮點類型,一般當作空值處理。所以要先去除NaN再進行分隔字元串#None和NaN的區別print(None的數據類型,type(None))from numpy import NaNprint(NaN的數據類型,type(NaN))

None的數據類型 <class NoneType>NaN的數據類型 <class float>

dateSer[0:3]

0 2018-01-011 2018-01-022 2018-01-06dtype: object

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

數據類型轉換:字元串轉換為日期#errors=coerce 如果原始數據不符合日期的格式,轉換後的值為空值#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)

3.5 數據排序

print(排序前的數據集)salesDf.head()

#按銷售日期進行升序排列salesDf=salesDf.sort_values(by=銷售時間, ascending=True)print(排序後的數據集)salesDf.head(3)

#重命名行名(index):排序後的列索引值是之前的行號,需要修改為從0到N的索引值salesDf=salesDf.reset_index(drop=True)salesDf.head()

3.6 異常值處理

#描述指標:查看出「銷售數量」值不能小於0salesDf.describe()

#刪除異常值:通過條件判斷篩選出數據#查詢條件querySer=salesDf.loc[:,銷售數量]>0#應用查詢條件print(刪除異常值前:,salesDf.shape)salesDf=salesDf.loc[querySer,:]print(刪除異常值後:,salesDf.shape)

刪除異常值前: (6549, 7)刪除異常值後: (6506, 7)

四、構建模型

4.1 業務指標1:月均消費次數=總消費次數/月份數

總消費次數:同一天內,同一個人發生的所有消費算作一次消費#根據列名(銷售時間,社區卡號),如果這兩個列值同時相同,只保留1條,將重複的數據刪除kpil_Df=salesDf.drop_duplicates( subset=[銷售時間,社保卡號]) #總消費次數:有多少行totalI=kpi1_Df.shape[0]print(總消費次數=,totalI)

總消費次數= 5342

計算月份數:時間範圍#第1步:按銷售時間升序排序kpi1_Df=kpi1_Df.sort_values(by=銷售時間, ascending=True)#重命名行名(index)kpi1_Df=kpi1_Df.reset_index(drop=True)

kpil_Df.head()

#第二步:獲取時間範圍#最小時間值startTime=kpil_Df.loc[0,銷售時間]#最大時間值endTime=kpil_Df.loc[totalI-1,銷售時間]#第三步:計算月份數#天數daysI=(endTime-startTime).days#月分數:運算符「//」表示取整monthsI=daysI//30print(月份數:,monthsI)

月份數: 5

#業務指標1:月均消費次數=總消費次數/月份數kpil_I=totalI//monthsIprint(業務指標1:月均消費次數=,kpil_I)

業務指標1:月均消費次數= 1068

4.2 指標2:月均消費金額= 總消費金額/月份數

#總消費金額totalMoneyF=salesDf.loc[:,實收金額].sum()#月均消費金額monthMoneyF=totalMoneyF/monthsIprint(業務指標2:月均消費金額=,monthMoneyF)

業務指標2:月均消費金額= 60802.022

4.3 指標3:客單價=總消費金額/總消費次數

客單價(per customer transaction)也即是平均交易金額

pct=totalMoneyF/totalIprint(業務指標3:客單價=,pct)

業務指標3:客單價= 56.909417821040805

推薦閱讀:

Python 數據分析(五):數據的處理
推薦相關梳理
用數據挖一挖豆瓣5.3的《長城》,水軍力量到底有多強大
《Python數據挖掘》筆記(七) 自動化文本摘要
介紹一位可能過時的咖狗神器XGBoost

TAG:數據挖掘 | 數據分析師 |