python微專業-數據分析師
一、數據清洗入庫體驗
1、常見文件讀寫方式參考隨筆:https://www.cnblogs.com/Eric15/p/10042342.html
2、python系統模塊 - os模塊介紹
os 模塊:提供了非常豐富的方法用來處理文件和目錄
import os print(os.name) # 輸出字符串指示正在使用的平台。如果是window 則輸出'nt',如果是Linux/Unix用戶,則輸出'posix' print(os.getcwd()) # 返回當前工作目錄,即當前Python腳本工作的目錄路徑 print(os.listdir()) # 返回當前工作目錄下的所有文件和目錄名 os.chdir("C:\users\") # 切換到目標路徑下 os.path.split('C:\\Users\\Hjx\\Desktop\\text.txt') # 將目錄路徑和文件名分開,返回一個元組:('C:\\Users\\Hjx\\Desktop', 'text.txt') os.remove("text2.txt") # 刪除文件 os.path.exists('C:\\Users\\Hjx\\Desktop\\heheh.txt') # 用於檢驗給出的路徑是否存在
3、絕對路徑與相對路徑
os.chdir('C:\\Users\\Hjx\\Desktop\\' ) # 絕對路徑 f2 = open('text.txt','r') # 相對路徑 print(f2.read()) # 上述中,通過chdir申明了目錄之后,接着可以直接給文件名 → 相對路徑
數據清洗及存取demo:
# demo1: 商鋪數據加載及存儲 要求: 1、成功讀取“商鋪數據.csv”文件 2、解析數據,存成列表字典格式:[{'var1':value1,'var2':value2,'var3':values,...},...,{}] 3、數據清洗: ① comment,price兩個字段清洗成數字 ② 清除字段缺失的數據 ③ commentlist拆分成三個字段,並且清洗成數字 4、結果存為.pkl文件
商鋪數據.csv:
代碼實現:
import pickle def fcm(s): # 清洗comment(評論數)數據,並轉換成int類型。 eg: "988 條點評" if "條" in s: return int(s.split(" ")[0]) else: return "缺失數據" def fpr(s): # 清洗price(價格)數據,並轉換成float類型。 eg:"人均 ¥81" if "¥" in s: return float(s.split("¥")[-1]) else: return "缺失數據" def fcl(s): # commentlist清洗函數:用空格分段,分別清洗出質量、環境及服務數據,並轉化為浮點型。 eg:"口味7.0 環境7.0 服務7.0" if " " in s: commentlist = s.split(" ") quality = float(commentlist[0][2:]) environment = float(commentlist[1][2:]) service = float(commentlist[2][2:-1]) return [quality,environment,service] else: return "缺失數據" f = open(r"C:\Users\Administrator\Desktop\商鋪數據.csv", "r", encoding="utf8") data_list = [] n =0 for i in f.readlines()[1:]: data = i.split(",") # print(i.split(",")) # 根據","分割,返回列表數據 classify = data[0] name = data[1] comment_count = fcm(data[2]) star = data[3] price = fpr(data[4]) address = data[5] commentlist = fcl(data[6]) if "缺失數據" in commentlist: quality = commentlist else: quality, enviroment, service = fcl(data[6]) if "缺失數據" not in [comment_count, price, quality]: # 判斷每條數據中是否存在缺失數據,如有則過濾 n += 1 # 用於計數 data_re = [ ["classify",classify], ["name",name], ["comment_count",comment_count], ["star",star], ["price",price], ["address",address], ["quality",quality], ["enviroment",enviroment], ["service",service] ] data_list.append(dict(data_re)) # 生成字典,並將數據追加到列表data_list 中 print("\n成功加載%i條數據"%n) f.close() print(data_list) print("\n數據加載完畢,總共加載了%i條數據"%n) # 將數據存儲到pkl文件中: f_pic = open(r"C:\Users\Administrator\Desktop\data.pkl", "wb") pickle.dump(data_list, f_pic) f_pic.close() print("數據存儲成功!") # 讀取data.pkl文件 f_pic = open(r"C:\Users\Administrator\Desktop\data.pkl", "rb") data = pickle.load(f_pic) f_pic.close() print("數據加載完畢,如下所示:") print(data)
二、數據分析核心技術
1. numpy 介紹
numpy學習參考隨筆:https://www.cnblogs.com/Eric15/p/10021362.html
numpy 數組是一個多維數組對象,稱為ndarray,其由兩部分組成:
①. 實際的數據
②. 描述這些數據的元數據
1)創建數組的方式
1.1)array() 函數,括號內可以是列表、元組、數組、生成器等
ar1 = np.array(range(10)) # 整型 ar2 = np.array([1,2,3.14,4,5]) # 浮點型 ar3 = np.array([[1,2,3],('a','b','c')]) # 二維數組:嵌套序列(列表,元祖均可) ar4 = np.array([[1,2,3],('a','b','c','d')]) # 注意嵌套序列數量不一時,多維數組會變一維數組 print(ar1,type(ar1),ar1.dtype) print(ar2,type(ar2),ar2.dtype) print(ar3,ar3.shape,ar3.ndim,ar3.size) # 二維數組,共6個元素 print(ar4,ar4.shape,ar4.ndim,ar4.size) # 一維數組,共2個元素 # 輸出 [0 1 2 3 4 5 6 7 8 9] <class 'numpy.ndarray'> int32 [ 1. 2. 3.14 4. 5. ] <class 'numpy.ndarray'> float64 [['1' '2' '3'] ['a' 'b' 'c']] (2, 3) 2 6 [[1, 2, 3] ('a', 'b', 'c', 'd')] (2,) 1 2
1.2)arange()函數,類似range()
np.arange(10)) # 返回0-9,整型 np.arange(10.0) # 返回0.0-9.0,浮點型 np.arange(5,12) # 返回5-11 np.arange(5.0,12,2) # 返回5.0-12.0,步長為2 np.arange(10000) # 如果數組太大而無法打印,NumPy會自動跳過數組的中心部分,並只打印邊角
1.3)linspace():返回在間隔[開始,停止] 上計算的num個均勻間隔的樣本
ar1 = np.linspace(2.0, 3.0, num=5) ar2 = np.linspace(2.0, 3.0, num=5, endpoint=False) ar3 = np.linspace(2.0, 3.0, num=5, retstep=True) print(ar1,type(ar1)) print(ar2) print(ar3,type(ar3)) # numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) # start:起始值,stop:結束值 # num:生成樣本數 # endpoint:如果為真,則包含最后一個數,否則不包含最后一個數。默認值為True。 # retstep:如果為真,返回(樣本,步長),其中步長是樣本之間的間距 → 輸出為一個包含2個元素的元祖,第一個元素為array,第二個為步長 # 輸出: [ 2. 2.25 2.5 2.75 3. ] <class 'numpy.ndarray'> [ 2. 2.2 2.4 2.6 2.8] (array([ 2. , 2.25, 2.5 , 2.75, 3. ]), 0.25) <class 'tuple'>
1.4)zeros()/ zeros_like()/ ones()/ ones_like()
ar1 = np.zeros(5) ar2 = np.zeros((2,2), dtype = np.int) print(ar1,ar1.dtype) print(ar2,ar2.dtype) print('------') # numpy.zeros(shape, dtype=float, order='C'):返回給定形狀和類型的新數組,用零填充。 # shape:數組緯度,二維以上需要用(),且輸入參數為整數 # dtype:數據類型,默認numpy.float64 # order:是否在存儲器中以C或Fortran連續(按行或列方式)存儲多維數據。 ar3 = np.array([list(range(5)),list(range(5,10))]) ar4 = np.zeros_like(ar3) print(ar3) print(ar4) print('------') # 返回具有與給定數組相同的形狀和類型的零數組,這里ar4根據ar3的形狀和dtype創建一個全0的數組 ar5 = np.ones(9) ar6 = np.ones((2,3,4)) ar7 = np.ones_like(ar3) print(ar5) print(ar6) print(ar7) # ones()/ones_like()和zeros()/zeros_like()一樣,只是填充為1 # 輸出: [ 0. 0. 0. 0. 0.] float64 [[0 0] [0 0]] int32 ------ [[0 1 2 3 4] [5 6 7 8 9]] [[0 0 0 0 0] [0 0 0 0 0]] ------ [ 1. 1. 1. 1. 1. 1. 1. 1. 1.] [[[ 1. 1. 1. 1.] [ 1. 1. 1. 1.] [ 1. 1. 1. 1.]] [[ 1. 1. 1. 1.] [ 1. 1. 1. 1.] [ 1. 1. 1. 1.]]] [[1 1 1 1 1] [1 1 1 1 1]]
1.5)eye()
np.eye() # 創建一個正方的N*N的單位矩陣,對角線值為1,其余為0 print(np.eye(5)) # 輸出: [[ 1. 0. 0. 0. 0.] [ 0. 1. 0. 0. 0.] [ 0. 0. 1. 0. 0.] [ 0. 0. 0. 1. 0.] [ 0. 0. 0. 0. 1.]]
2)多維數組屬性
import numpy as np ar = np.array([1,2,3,4,5,6,7]) print(ar) # 輸出數組,注意數組的格式:中括號,元素之間沒有逗號(和列表區分) print(ar.ndim) # 輸出數組維度的個數(軸數),或者說“秩”,維度的數量也稱rank print(ar.shape) # 數組的維度,對於n行m列的數組,shape為(n,m) print(ar.size) # 數組的元素總數,對於n行m列的數組,元素總數為n*m print(ar.dtype) # 數組中元素的類型,類似type()(注意了,type()是函數,.dtype是方法) print(ar.itemsize) # 數組中每個元素的字節大小,int32l類型字節為4,float64的字節為8 print(ar.data) # 包含實際數組元素的緩沖區,由於一般通過數組的索引獲取元素,所以通常不需要使用這個屬性
3)numpy 通用函數
3.1)數組形狀:.T/ .reshape()/ .resize()
ar1 = np.arange(10) ar2 = np.ones((5,2)) print(ar1,'\n',ar1.T) print(ar2,'\n',ar2.T) print('------') # .T方法:轉置,例如原shape為(3,4)/(2,3,4),轉置結果為(4,3)/(4,3,2) → 所以一維數組轉置后結果不變 ar3 = ar1.reshape(2,5) # 用法1:直接將已有數組改變形狀 ar4 = np.zeros((4,6)).reshape(3,8) # 用法2:生成數組后直接改變形狀 ar5 = np.reshape(np.arange(12),(3,4)) # 用法3:參數內添加數組,目標形狀 print(ar1,'\n',ar3) print(ar4) print(ar5) print('------') # numpy.reshape(a, newshape, order='C'):為數組提供新形狀,而不更改其數據,所以元素數量需要一致!! ar6 = np.resize(np.arange(5),(3,4)) print(ar6) # numpy.resize(a, new_shape):返回具有指定形狀的新數組,如有必要可重復填充所需數量的元素。 # 注意了:.T/.reshape()/.resize()都是生成新的數組!!! # 輸出: [0 1 2 3 4 5 6 7 8 9] [0 1 2 3 4 5 6 7 8 9] [[ 1. 1.] [ 1. 1.] [ 1. 1.] [ 1. 1.] [ 1. 1.]] [[ 1. 1. 1. 1. 1.] [ 1. 1. 1. 1. 1.]] ------ [0 1 2 3 4 5 6 7 8 9] [[0 1 2 3 4] [5 6 7 8 9]] [[ 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0.]] [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] ------ [[0 1 2 3] [4 0 1 2] [3 4 0 1]]
3.2)數組的復制
ar1 = np.arange(10) ar2 = ar1 print(ar2 is ar1) ar1[2] = 9 print(ar1,ar2) # 回憶python的賦值邏輯:指向內存中生成的一個值 → 這里ar1和ar2指向同一個值,所以ar1改變,ar2一起改變 ar3 = ar1.copy() print(ar3 is ar1) ar1[0] = 9 print(ar1,ar3) # 使用copy方法可以實現完整復制,改變該數組值不影響原數組值 # 輸出: True [0 1 9 3 4 5 6 7 8 9] [0 1 9 3 4 5 6 7 8 9] False [9 1 9 3 4 5 6 7 8 9] [0 1 9 3 4 5 6 7 8 9]
3.3)數組類型轉換:.satype()
# 實現數組類型轉換 ar1 = np.arange(10,dtype=float) print(ar1,ar1.dtype) print('-----') # 可以在參數位置設置數組類型 ar2 = ar1.astype(np.int32) print(ar2,ar2.dtype) print(ar1,ar1.dtype) # a.astype():轉換數組類型 # 注意:養成好習慣,數組類型用np.int32,而不是直接int32 # 輸出: [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] float64 ----- [0 1 2 3 4 5 6 7 8 9] int32 [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] float64
3.4)數組簡單運算
# 與標量的運算 ar = np.arange(6).reshape(2,3) print(ar + 10) # 加法 print(ar * 2) # 乘法 print(1 / (ar+1)) # 除法 print(ar ** 0.5) # 冪 print(ar.mean()) # 求平均值 print(ar.max()) # 求最大值 print(ar.min()) # 求最小值 print(ar.std()) # 求標准差 print(ar.var()) # 求方差 print(ar.sum(), np.sum(ar,axis = 0)) # np.sum():求和 ; np.sum(ar,axis=0/1):axis為0,按列求和;axis為1,按行求和 ,注意看輸出結果 print(np.sort(np.array([1,4,3,2,5,6]))) # 排序
輸出:
[[10 11 12] [13 14 15]] [[ 0 2 4] [ 6 8 10]] [[ 1. 0.5 0.33333333] [ 0.25 0.2 0.16666667]] [[ 0. 1. 1.41421356] [ 1.73205081 2. 2.23606798]] 2.5 5 0 1.70782512766 2.91666666667 15 [3 5 7] [1 2 3 4 5 6]
4)numpy索引及切片
4.1)基本索引及切片
# 一維數組索引及切片 ar = np.arange(20) print(ar) print(ar[4]) print(ar[3:6]) print('-----') # 二維數組索引及切片 ar = np.arange(16).reshape(4,4) print(ar, '數組軸數為%i' %ar.ndim) # 4*4的數組 print(ar[2], '數組軸數為%i' %ar[2].ndim) # 切片為下一維度的一個元素,所以是一維數組 print(ar[2][1]) # 二次索引,得到一維數組中的一個值 print(ar[1:3], '數組軸數為%i' %ar[1:3].ndim) # 切片為兩個一維數組組成的二維數組 print(ar[2,2]) # 切片數組中的第三行第三列 → 10 print(ar[:2,1:]) # 切片數組中的1,2行、2,3,4列 → 二維數組 print('-----') # **三維數組索引及切片 ar = np.arange(8).reshape(2,2,2) print(ar, '數組軸數為%i' %ar.ndim) # 2*2*2的數組 print(ar[0], '數組軸數為%i' %ar[0].ndim) # 三維數組的下一個維度的第一個元素 → 一個二維數組 print(ar[0][0], '數組軸數為%i' %ar[0][0].ndim) # 三維數組的下一個維度的第一個元素下的第一個元素 → 一個一維數組 print(ar[0][0][1], '數組軸數為%i' %ar[0][0][1].ndim) # 輸出: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19] 4 [3 4 5] ----- [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15]] 數組軸數為2 [ 8 9 10 11] 數組軸數為1 9 [[ 4 5 6 7] [ 8 9 10 11]] 數組軸數為2 10 [[1 2 3] [5 6 7]] ----- [[[0 1] [2 3]] [[4 5] [6 7]]] 數組軸數為3 [[0 1] [2 3]] 數組軸數為2 [0 1] 數組軸數為1 1 數組軸數為0
4.2)布爾型索引及切片(重要)
ar = np.arange(12).reshape(3,4) i = np.array([True,False,True]) j = np.array([True,True,False,False]) print(ar) print(i) print(j) print(ar[i,:]) # 在第一維度做判斷,只保留True,這里第一維度就是行,ar[i,:] = ar[i](簡單書寫格式) print(ar[:,j]) # 在第二維度做判斷,這里如果ar[:,i]會有警告,因為i是3個元素,而ar在列上有4個 # 布爾型索引:以布爾型的矩陣去做篩選 m = ar > 5 print(m) # 這里m是一個判斷矩陣 print(ar[m]) # 用m判斷矩陣去篩選ar數組中>5的元素 → 重點!后面的pandas判斷方式原理就來自此處 # 輸出: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [ True False True] [ True True False False] [[ 0 1 2 3] [ 8 9 10 11]] [[0 1] [4 5] [8 9]] [[False False False False] [False False True True] [ True True True True]] [ 6 7 8 9 10 11]