標籤:

小試牛刀——Python數據分析初體驗

看到數據分析大神們用一幅幅精美、形象的圖片展示數據背後的趨勢,心裡感覺這些人老牛逼了,他們是怎麼做到用一行行代碼生成這些普通人一眼就看懂的圖示呢?作為數據分析的初學者,我也幻想著自己能早日達到這樣的水平,在別人面前炫一把。學習完猴子的課程前3次基礎內容後,終於在本次學習內容中慢慢走進了數據分析的正廳。

在進行數據處理和分析之前,我們要先了解數據的存儲形式。在Python中主要用到Numpy和Pandas包來定義一維數組和二維數組。

1、用Numpy定義一維數組:(array)

#Numpy 一維數組#定義:一維數組arraya = np.array([2,3,4,5])

2、用Numpy定義二維數組:

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

3、用Pandas定義一維數組:(series)

#Pandas一維數據結構stockS=pd.Series([54.74,190.9,173.14,1050.3,181.86,1139.49],)

4、用Pandas定義二維數組:數據框(DataFrame)

#Pandas數據框(DataFrame)#第1步:定義一個字典,映射列名與對應列的值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]}#第2步:定義數據框,參數傳入字典salesDf=pd.DataFrame(salesDict)

在對數據處理的過程中,經常會使用到「切片」功能,就是選擇自己想要的那一部分內容,在python中使用「iloc」和「loc」這兩條命令語句。

iloc屬性用於根據位置查詢值#1)查詢元素:salesDf.iloc[0,1]#2)獲取第1行:salesDf.iloc[0,:]#3)獲取第1列:salesDf.iloc[:,0]loc屬性用於根據索引查詢值#1)查詢元素:salesDf.loc[0,商品編碼]#2)獲取第1行:salesDf.loc[0,:]#3)獲取第1列:salesDf.loc[:,商品名稱]

數據分析的基本過程

數據分析主要分為5個步驟:

  1. 提出問題:期望從數據中得到哪些結果
  2. 理解數據:了解數據的存儲形式,數據類型和格式等
  3. 數據清洗:選擇子集—列名重命名—缺失數據處理—數據類型轉換—數據排序—異常值處理
  4. 構建模型:根據第一步提出的問題,構建演算法
  5. 數據可視化:用易於理解的圖表展示結果

下面,具體舉例來理解以上數據分析的5個步驟。

數據來源為北京朝陽醫院2018年藥品銷售數據,以excel格式存儲。

1、提出問題:期望得到月均消費次數、月均消費金額、客單價、消費趨勢這四個指標

2、理解數據:

1)根據存儲位置,讀取Excel數據,統一先按照str讀入,之後轉換

fileNameStr=c:/hj/朝陽醫院2018年銷售數據.xlsxxls = pd.ExcelFile(fileNameStr,dtype=object)salesDf = xls.parse(Sheet1,dtype=object)

2)列印前幾行:

salesDf.head()

3)統計有多少行,多少列:

salesDf.shape

(6578, 7),即總共有6578行,7列數據

4)查看列的數據類型:

salesDf.dtypes

object為字元串類型

3、數據清洗:

(1)選擇子集(本案例不需要選擇子集)

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

上述代碼用到切片功能loc,即選擇第1到5行,列名從"購葯時間「到」銷售數量「的數據。

(2)列名重命名:把」購葯時間「重命名為」銷售時間「

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

(3)缺失數據處理:刪除列(銷售時間,社保卡號)中為空的行

#how=any在給定的任何一列中有缺失值就刪除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

實收金額 float64

由於」銷售時間「這一列中既有日期又有星期幾,為了下面的數據處理方便,我們希望只留下日期,這裡就要用到字元串分割工具split( ),注意引號之間有個空格。

定義函數:分割銷售日期,獲取銷售日期輸入:timeColSer銷售時間這一列,是個Series數據類型輸出:分割後的時間,返回也是個Series數據類型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[:,銷售時間]=dateSer#字元串轉換為日期格式#errors=coerce如果原始數據不符合日期的格式,轉換後的值為NaT#format 是你原始數據中日期的格式salesDf.loc[:,銷售時間]=pd.to_datetime(salesDf.loc[:,銷售時間], format=%Y-%m-%d, errors=coerce)salesDf.dtypes

運行結果為:

銷售時間 datetime64[ns]

社保卡號 object

商品編碼 object

商品名稱 object

銷售數量 float64

應收金額 float64

實收金額 float64

dtype: object

轉換日期過程中不符合日期格式的數值會被轉換為空值None,這裡刪除列(銷售時間,社保卡號)中為空的行salesDf=salesDf.dropna(subset=[銷售時間,社保卡號],how=any)

刪除空值行後還剩6549行數據。

(5)排序:為了讓數據看著更有規律

by:按哪幾列排序ascending=True 表示降序排列,ascending=False表示升序排列#按銷售日期進行升序排列salesDf=salesDf.sort_values(by=銷售時間, ascending=True)

(6)異常值處理

首先查看數據的描述統計信息

#每一列的描述統計信息:salesDf.describe()

我們發現上面塗黃的數據出現了負值,而銷售數量不可能出現負數,因此,這些都屬於異常值,為了確保結果的真實性,我們需要刪除這些異常值。

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

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

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

4、構建模型

經過上面數據清洗的幾個步驟後,我們得到了排列更規則,更符合實際,更可靠的數據,就像燒菜前我們把菜都洗好切好,調料都已經擺放在邊上,就等著下鍋了。

接下來,我們就要根據第一步具體的問題來構建演算法。

業務指標1:月均消費次數=總消費次數/月份數(同一天內,同一個人發生的所有消費算作一次消費

#計算總消費次數#step1:刪除重複數據kpi1_Df=salesDf.drop_duplicates( subset=[銷售時間,社保卡號])#step2:計算有多少行totalI=kpi1_Df.shape[0]print(總消費次數=,totalI)總消費次數= 5342#計算月份數#step1:排序#按銷售時間升序排序kpi1_Df=kpi1_Df.sort_values(by=銷售時間, ascending=True)#重命名行名(index)kpi1_Df=kpi1_Df.reset_index(drop=True)#step2:獲取時間範圍#最小時間值startTime=kpi1_Df.loc[0,銷售時間]#最大時間值endTime=kpi1_Df.loc[totalI-1,銷售時間]#step3:計算月份數#天數daysI=(endTime-startTime).days#月份數:運算符「//」表示取整除#返回商的整數部分,例如9//2輸出結果是4monthsI=daysI//30print(月份數:,monthsI)

月份數: 6

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

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

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

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

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

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

totalMoneyF:總消費金額totalI:總消費次數pct=totalMoneyF/totalIprint(客單價:,pct)

客單價: 56.909417821040805

到現在為止,我們已經完成了前面三個問題的解答,還剩最後一個」消費趨勢「需要用到可視化工具才能實現,猴子老師在這裡嘎然而止,結束了本次課程,就像電視劇播到了最精彩的地方開始放片尾曲和下集預告。

通過本次課程的學習,我了解了數據分析的具體過程,並通過具體案例,熟悉了各個步驟的處理方法,掌握了相關工具包的使用,在實際敲代碼的過程中領略了編程語言的強大。去年,我卡在了第四關,今年,我順利完成了第四關,也算是從跌倒的地方爬了起來。接下來,我將繼續跟著猴子學習後期的課程,探索數據分析之美。

推薦閱讀:

國外SaaS圖譜之商業智能BI(持續更新)
物聯網時代借大數據洞察消費行為
地震運用大數據預測可能性
2017年嘗試從零開始學習數據分析的學習計劃

TAG:大數據分析 |