python数据分析可视化
python數(shù)據(jù)分析&可視化
【目錄】
1.jupyter
2.pandas
2.數(shù)據(jù)分析
3.數(shù)據(jù)展現(xiàn)與報告撰寫
4.Apriori算法
5.RFM模型
6.NumPy
7.可視化進階
8.機器學習導論
(一)Jupyter
(二)pandas
import pandas as pd1. pandas 庫的基本數(shù)據(jù)結(jié)構(gòu)
1. Series
①組成
Series 主要由一組數(shù)據(jù)及其對應的索引組成。②創(chuàng)建
? pd.Series() 就是創(chuàng)建 Series 對象的方法。這個方法包含的參數(shù)有很多。
? 主要先講解一種借助列表來創(chuàng)建 Series 對象的方法,也就是:pd.Series(data)。當我們將列表傳給參數(shù) data 之后,在默認情況下,pd.Series(data)會自動為列表中的每一個元素分配對應的數(shù)字索引。默認索引是從 0 開始,以 0, 1, 2, 3,… 的形式按序分配給列表中的元素。當然,也可以人為設定 Series 對象的索引,只不過這不是這節(jié)課的重點。
輸入;
# 創(chuàng)建Series對象 surname = pd.Series(['趙', '錢', '孫', '李'], index = ['學生1', '學生2', '學生3', '學生4']) # 查看surname surname輸出:
? 但其實除了列表以外,還有很多其他的方式可以創(chuàng)建Series:
2.DataFrame
①結(jié)構(gòu)
? DataFrame對象是一種表格型的數(shù)據(jù)結(jié)構(gòu),包含行索引、列索引以及一組數(shù)據(jù)。
②創(chuàng)建
? 創(chuàng)建 DataFrame 對象的方法是:pd.DataFrame()。和創(chuàng)建 Series 對象一樣,創(chuàng)建 DataFrame 對象的參數(shù)也有很多。這節(jié)課會主要講解一種借助字典來創(chuàng)建 DataFrame 對象的方法,也就是:pd.DataFrame(data)。這里需要將一組數(shù)據(jù)傳給參數(shù) data,數(shù)據(jù)的形式可以是字典。
? 不過要注意:各鍵所對的值的長度如果不相等,就意味著數(shù)據(jù)是長短不一的,這樣的字典如果傳給了參數(shù)data,則會報錯。
? 方法一:傳入字典
# 創(chuàng)建 DataFrame 對象 class_df = pd.DataFrame({'年齡': [25, 18, 23, 18],'性別': ['女', '女', '女', '男']}) # 查看 class_df class_df? 方法二:傳入n維數(shù)組
# 創(chuàng)建DataFrame對象 import numpy as np class_df2 = pd.DataFrame(np.array([[25, '女'],[18, '女'],[23, '女'],[18, '男']]),columns = ['年齡', '性別'],index = [1, 2, 3, 4]) # 查看 class_df2 class_df2? 方法三:傳入多個嵌套列表
goods_info = [['巧克力', 77.675, '47箱', '廣東佛山倉'], ['牛奶', 58.755, '40箱', '廣東揭陽倉'], ['威化餅干', 7.385, '285盒', '廣西南寧倉'], ['火腿腸', 34.823, '20件', '廣西柳州倉'], ['巧克力', 62.648, '30箱', '廣東揭陽倉'], ['牛奶', 45.75, '12箱', '廣西柳州倉'], ['威化餅干', 5.235, '148盒', '廣東佛山倉'], ['火腿腸', 33.736, '28件', '廣東佛山倉'] ]goods_df = pd.DataFrame(goods_info) goods_df觀察兩個數(shù)據(jù)的內(nèi)容,可以發(fā)現(xiàn)1.3的區(qū)別。
1)以字典作為數(shù)據(jù)傳入時,字典的鍵會作為 DataFrame 對象的列名顯示,而字典的值會作為對象的列數(shù)據(jù)顯示。
2)以嵌套列表作為數(shù)據(jù)傳入時,列表的元素會作為 DataFrame 對象的行數(shù)據(jù)顯示,且會為數(shù)據(jù)默認生成從 0 開始的列名。
③列名設置
1 帶列名直接創(chuàng)建
# 設置列表 students_info = [['小藍', '語文', '79'], ['小邱', '數(shù)學', '83'], ['小李', '英語', '92']]# 使用列表創(chuàng)建 DataFrame 對象,同時設置列名 students_df = pd.DataFrame(students_info, columns=['姓名', '科目', '分數(shù)']) students_df2 補充、修改列名(賦值操作)
# 修改 goods_df 的列名 goods_df.columns = ['名稱', '單價', '庫存', '地址'] goods_df3.Series 對象和 DataFrame 對象的聯(lián)系
? DataFrame 對象可以被看作是由 Series 對象所組成的。想要驗證這層聯(lián)系,可以通過 df['列索引'] 這個索引操作來實現(xiàn)。
2.導入數(shù)據(jù)文件
? pandas 庫為讀取各種文件類型的數(shù)據(jù)提供了非常簡便高效的方法。
1.csv
pd.read_csv(path, encoding) 就是其中一種高效讀取 csv 文件的方法,返回的是一個 DataFrame 對象。這個方法有很多參數(shù),這里先介紹兩種最常用的:path,encoding。
? 對于參數(shù) path,需要傳一個文件路徑給它。可以是相對路徑,也可以是絕對路徑。對于參數(shù) encoding,需要傳一個文件編碼格式給它。文件編碼格式的選取需要根據(jù)所讀文件的編碼格式來定。
2.excel
? 它可以以 DataFrame 格式讀取 Excel 文件的數(shù)據(jù),并返回一個 DataFrame 對象。
3.部分總結(jié)
4.數(shù)據(jù)預處理
1.數(shù)據(jù)清洗
首先了解一下查看的方法:
-
直接輸入 DataFrame 對象的名稱能查看數(shù)據(jù)的前后 5 行
-
可以使用df.head()或df.tail()方法查看數(shù)據(jù)。對DataFrame 對象使用 df.head() 方法默認可以查看數(shù)據(jù)的前 5 行,df.tail() 方法則默認可以查看數(shù)據(jù)的后 5 行。當然自己加進去數(shù)字,就是前、后幾行的意思。
①處理缺失值
**1 查看基本信息 **
? 在實際的數(shù)據(jù)分析項目中,面對龐大的數(shù)據(jù)我們自然不能依賴肉眼的觀測。有一個工具能幫助我們提煉出基本的數(shù)據(jù)信息,從而能讓我們對于整體的數(shù)據(jù)有一個大概的印象。這個方法就是df.info()。
當非空數(shù)據(jù)與數(shù)據(jù)總量不一致時,說明這份數(shù)據(jù)有可能存在缺失值,處理這些缺失值的第一步,就是找到它們。
2 查找缺失值
? 在 pandas 庫中,我們可以使用 isna() 方法來查找 DataFrame 對象以及 Series 對象中的缺失值。它可以將查找結(jié)果以 DataFrame 對象或者 Series 對象的形式進行返回。df.isna()返回的是 DataFrame 對象,Series.isna() 返回的就是 Series 對象。返回對象中的內(nèi)容都是布爾值,缺失數(shù)據(jù)會用 True 來表示,False 則代表這里的數(shù)據(jù)不缺失。
3 刪除缺失值(!記得一定要進行賦值操作,把它重新賦給原來那個)
# 刪除所有缺失值 mask_data = mask_data.dropna() # 查看數(shù)據(jù)基本信息總結(jié) mask_data.info()? 如果我們需要針對某幾列的缺失數(shù)據(jù)進行刪除,就需要用到df.dropna()的 subset 參數(shù)。它可以指定 dropna() 方法刪除一列或多列數(shù)據(jù)中含有缺失值的行。我們可以把要指定的列名寫進中括號[]中,然后賦值給 subset 參數(shù),就可以限定 dropna() 方法的刪除范圍。
# 刪除'品牌', '上牌時間', '里程數(shù)(km)', '保值率'四列數(shù)據(jù)缺失的行 test_data = test_data.dropna(subset=['品牌', '上牌時間', '里程數(shù)(km)', '保值率']) # 查看 test_data 的基本信息總結(jié) test_data.info()②處理重復值
1 查找重復值
? 我們可以直接使用 df.duplicated()(中文意思:重復的)方法來查找 DataFrame 對象中的重復數(shù)據(jù)。
? 可以看到,這里的返回結(jié)果很長,我們完全沒有辦法用肉眼進行觀察。
? 我們可以將 mask_data.duplicated() 返回的結(jié)果放入中括號 [] 中,用來索引 mask_data 數(shù)據(jù),查看 mask_data 數(shù)據(jù)中重復的行。
2 刪除重復行
? 可以使用 pandas 庫的 df.drop_duplicates() 方法直接刪除 DataFrame 對象中重復出現(xiàn)的整行數(shù)據(jù)。
? 我們能看見 mask_data 的表頭下面是空的,說明到這里已經(jīng)沒有重復數(shù)據(jù)了。
? 值得一提的是,df.drop_duplicates() 方法并不會將所有重復的行都刪除。這里你要弄清重復出現(xiàn)的行與重復的行之間的區(qū)別,在 pandas 庫中只有重復出現(xiàn)的數(shù)據(jù)才會被判定為重復數(shù)據(jù).,df.drop_duplicates() 方法刪除的也都是重復出現(xiàn)的行,因此所有重復數(shù)據(jù)的第一行都會保留。
######③處理異常值
1 檢查異常值
? 介紹一個檢查數(shù)據(jù)是否存在異常的方法 —— describe()。describe 單詞在英語里是描述的意思,而在 pandas 庫中 describe() 方法則可以查看 Series 對象或者DataFrame 對象的 描述性統(tǒng)計信息。
? 在計算機系統(tǒng)里,e+n 代表的是 10 的 n 次方。
2 抽取數(shù)據(jù)范圍(布爾索引)
? 在pandas庫中,有一種篩選數(shù)據(jù)的方法叫做布爾索引。之前我們有學過使用 df['列索引'] 來提取某一列的信息。在 pandas 庫中,我們還可以在 df[] 中通過表達式的形式來提取一定范圍的數(shù)據(jù)。比如我們想選擇 mask_data 數(shù)據(jù)中,單價一列小于等于 200 的數(shù)據(jù),就可以設置條件表達式 mask_data['單價'] <= 200。把它加入括號中索引:mask_data[mask_data['單價'] <= 200],就可以選取 mask_data 數(shù)據(jù)中單價這一列小于等于 200 的數(shù)據(jù)。
# 篩選單價小于等于 200 的數(shù)據(jù) mask_data = mask_data[mask_data['單價'] <= 200]? 要注意,布爾索引用的也是中括號嗷。
總結(jié):
2.數(shù)據(jù)整理
1.日期datetime
① 轉(zhuǎn)換日期數(shù)據(jù)
? 在 pandas 庫中我們可以使用 pd.to_datetime(arg, format) 來將 DataFrame 對象或者 Series 對象的數(shù)據(jù)類型轉(zhuǎn)換成 datetime 類型。其中的 arg 參數(shù)為我們要轉(zhuǎn)換的數(shù)據(jù),它可以是DataFrame 對象或 Series 對象。我們這次要轉(zhuǎn)換的數(shù)據(jù)為 mask_data 中的’日期’字段,所以對應的 arg 參數(shù)就是 mask_data[‘日期’]。format 參數(shù)為 datetime 類型的日期格式,比如說這份數(shù)據(jù),它是以年-月-日的形式出現(xiàn)的,那么它對應的 format 就是 ‘%Y-%m-%d’(year-month-day的縮寫)。
# 轉(zhuǎn)換日期數(shù)據(jù),并設置對應的日期格式 date_data = pd.to_datetime(mask_data['日期'], format = '%Y-%m-%d') # 查看 date_data date_data? 將’日期’字段轉(zhuǎn)換成 datetime 類型后,我們就可以直接從中提取月份信息。
② 提取月份信息
? 這一步需要用到 Series.dt.month。其中的 Series 指的就是剛才日期數(shù)據(jù)轉(zhuǎn)換完后的 Series 對象,我將它賦值到了變量 date_data。Series.dt 可以把 datetime 類型的數(shù)據(jù)轉(zhuǎn)成一種方便我們提取日期或時間的對象。這種對象包含多種屬性,其中有 year(年)、month(月)、day(日)等。想要獲取這份數(shù)據(jù)的年、月、日的信息,可以通過 Series.dt.year、Series.dt.month 以及 Series.dt.day 來獲取。
# 提取日期數(shù)據(jù)中的月份信息 month_data = date_data.dt.month③ 添加新列
? 在 pandas 庫中,我們可以直接用 df['colname'] = Series 的方式來為原數(shù)據(jù)添加新的一列。colname 指的是要添加的新列的列名。在這個案例中,colname 就是月份。也就是說直接對新增的這列數(shù)據(jù)進行賦值,就能為 DataFrame 對象添加新列。因此最后添加’月份’字段到原數(shù)據(jù)的代碼就是:mask_data['月份'] = month_data。
# 將月份數(shù)據(jù)添加到原數(shù)據(jù)中 mask_data['月份'] = month_data # 查看原數(shù)據(jù) mask_data④ 總結(jié)
2.數(shù)據(jù)排序
①排序sort_values
sort_values() 方法,可以對指定列進行排序操作。(默認是升序排列)
#根據(jù)某列的值進行升序排序 sorted_goods=newgoods_df.sort_values(by='單價') #如果我們不想對上面的數(shù)據(jù)集進行排序,只想提取出【單價】列,單獨進行排序 newgoods_df['單價'].sort_values()? 另外,不單是 DataFrame 對象可以調(diào)用 sort_values() 方法,Series 對象也能調(diào)用該方法。但要注意的是,使用 DataFrame 對象調(diào)用 sort_values() 方法時,可以通過參數(shù) by 來指定某一列。而 Series 對象調(diào)用該函數(shù)時,函數(shù)沒有參數(shù) by。原因是 Series 對象不具備列索引(列名)。這一細節(jié)點,在書寫代碼時需要多加留意。
②重置索引
# 重置數(shù)據(jù) sorted_goods 的行索引 reset_goods = sorted_goods.reset_index(drop=True) reset_goods3.數(shù)據(jù)四舍五入
# 保留【體重】列的數(shù)據(jù)到一位小數(shù) humans_df['體重']=round(humans_df['體重'],1) humans_df? 這里有兩個是一定要注意的,一個是注意第一行是把df里的某一列重新賦值,而不是對整個df賦值;還要注意round是獨立函數(shù),并不需要跟在什么再加個點的后面。
4.函數(shù)處理 s.agg(func)
①單個函數(shù)處理
? 方法 agg() 中的參數(shù) func 可以為自定義的函數(shù)名,這里在使用時需要注意,傳入自定義的函數(shù)時,只需要寫上函數(shù)名,不需要加上括號以及函數(shù)的參數(shù)。
#定義一個切掉最后一個字符的函數(shù)(可用來去掉數(shù)值后的單位) def new_fuc(data):number=data[:-1]return int(number)# 使用 agg() 方法對【庫存】列的數(shù)據(jù)進行切片處理 reset_goods['庫存'] = reset_goods['庫存'].agg(new_func) reset_goods? 其實這個傳入的數(shù)據(jù)類型是要很重視的!!對吧因為這個稍微有那么一點點奇怪至少超出我現(xiàn)有的底層邏輯范圍,我暫時就只能構(gòu)建一下中層邏輯了。
? 雖說這個函數(shù)對傳入的data切去了最后一個字符,但我們要認清data的本質(zhì),它是某一列中的一個,也就是說,這是對待某一個對象的函數(shù),不是對某一列的函數(shù),所以必然用不到for i in xxx的循環(huán)去遍歷某一個列呀,因為它在被agg使用的時候就包含了這樣的逐個取出了。也就是說,agg這個函數(shù)的使用,本身就是對這一列的每一個元素逐個使用了!所以下面這段代碼一定是不對的!同時還忘記了非常關(guān)鍵的return!
#錯誤代碼示例 ## 定義函數(shù),以替換【數(shù)量】列的“-”為 0 #def exchange(data): # for i in range(len(data)): # if data[i]='-': # data[i]=0 #foods_df['數(shù)量'].agg(exchange)#正確代碼示范 def exchange(data):if data='-':data=0return data foods_df['數(shù)量'].agg(exchange)②多個函數(shù)處理(傳入字典、且只支持部分特定函數(shù))
# 定義字典 dict_2 !! 注意后面不帶括號嗷 dict_2 = {'單價': 'mean', '庫存': 'sum' } # 同時計算各食品的平均單價和總庫存量 reset_goods.groupby('名稱').agg(dict_2)? 代碼可分為3步進行理解:
1)使用 reset_goods.groupby('名稱') 讓數(shù)據(jù)按【名稱】列進行分組;
2)定義一個字典 dict_2,字典的鍵為我們需要操作的列名,如 '單價'、'庫存'。字典的值為我們需要操作的函數(shù)名,這里我們需要求平均值函數(shù) mean(),求和函數(shù) sum()。(可使用的函數(shù)可參照下表:)同樣需要注意的是,操作的函數(shù)只需要函數(shù)名,不需要函數(shù)名后的括號以及函數(shù)的參數(shù)。
3)分組后的數(shù)據(jù)調(diào)用 agg() 方法時,為方法的參數(shù) func 傳入字典 dict_2,可以同時得到各食品的平均單價和總庫存量。
5.數(shù)據(jù)類型轉(zhuǎn)換
? Python 提供了一個 astype() 方法,該方法可以將 Series/DataFrame 對象轉(zhuǎn)換為指定的數(shù)據(jù)類型。astype() 方法中的參數(shù) dtype,我們可以為其賦上需要的數(shù)據(jù)類型,如 int、str 等。其中,由于參數(shù) dtype 是 astype() 方法的第一個位置參數(shù),所以我們在使用時無需寫為 astype(dtype=int),可以直接寫為 astype(int)。
6.數(shù)據(jù)批量替換
? replace() 方法中的參數(shù) to_replace 可以是一個字典,字典可以將指定的列數(shù)據(jù)替換為不同的值。
亂入階段小小結(jié):
5.數(shù)據(jù)寫入
1.csv
? 使用 df.to_csv() 方法,將清洗好的數(shù)據(jù)寫入 csv 文件中。
# 保存清洗干凈的數(shù)據(jù) mask_data.to_csv('./工作/mask_data_clean.csv', encoding = 'utf-8')?
? 打開文件后你會發(fā)現(xiàn),最左側(cè)多了一列數(shù)據(jù)。這個數(shù)據(jù)是 DataFrame 對象的行索引。pandas 庫將 csv 文件讀取為 DataFrame對象 時都會自動生成行索引。所以我們寫入時也會把行索引單獨作為一列寫進數(shù)據(jù)文件中。這里我們可以使用 df.to_csv() 方法的 index 參數(shù)來限制 DataFrame 對象的行索引是否寫入到 csv 文件。它的默認值為 True,會讓你寫入的 csv 文件包含一列行索引。如果我們把這個參數(shù)設置為 index = False 就可以取消寫入行索引,不用將行索引那一列寫入 csv 文件。
# 保存清洗干凈的數(shù)據(jù),并取消寫入行索引 mask_data.to_csv('./工作/mask_data_clean.csv', index = False)2.excel
? to_excel() 函數(shù)可以以 DataFrame 格式將數(shù)據(jù)寫入到 Excel 文件。
? 因為 Excel 表中默認有行索引,所以如果數(shù)據(jù)的行索引在工作簿中不具備參考價值,建議不寫入到工作簿中。
階段性小總結(jié):
1.基本的數(shù)據(jù)處理
2.較為進階的數(shù)據(jù)處理
6. 數(shù)據(jù)分析(分組聚合)
1.單層分組聚合
? 單層分組聚合操作指的是針對某一個組進行聚合操作。
? df.groupby(by)['列索引'].mean()即為按某列索引分組并求出該組的平均值的方法。
? 注意,那個by的地方,圓括號里帶不帶方括號都可,結(jié)果一樣。但是一定要理解原理,這里的方括號可行只是因為可以看作一個只有一個內(nèi)容的列表吧,因為有多層分組的存在才導致了它可行,但你可以看到,它絕對不是作為col那樣的含義,因為在多層里再套方括號,它就不行了。
grade_df2 =grade_df.groupby(['性別'])['成績'].median() grade_df2 = grade_df.groupby('性別')['成績'].median()?
? 求平均值只是聚合操作的一種,聚合操作還有很多,幾個常用的聚合操作方法如下:
2. 多層分組聚合
? 唯一的不同點在于索引的層數(shù)上。層數(shù)的不同體現(xiàn)在參數(shù) by 的賦值方式上。在單層分組聚合操作的時候,只需要將一個列索引傳給參數(shù) by 就可以了。而多層分組聚合操作需要傳多個列索引給參數(shù) by。
? 需要注意的是,這些列索引在傳進參數(shù) by 之前,需要先被放進一個“容器”里,這個容器可以是列表。
# 獲取不同性別的學生處于不同班級時的平均分 grade_df4 = grade_df.groupby(['性別', '班級'])['成績'].mean() # 查看grade_df4 grade_df4? 注意,里面可不能再套方括號啦。
如果再多一層:
? 雖然通過多層分組聚合的方法,可以求出不同組別下的學生考試成績的情況,但是返回的結(jié)果看起來卻有些冗雜,所有的組別信息都扎堆出現(xiàn)在了一個 Series 對象的索引中。
? s.unstack() 函數(shù)就是解決這個問題的常見方法。它可以將一個多層分組聚合后的 Series 對象轉(zhuǎn)變成 DataFrame 對象。
# 對grade_df5使用unstack函數(shù) grade_df5.unstack()? s.unstack() 這個方法是針對多層分組聚合后的 Series 對象來使用的。作用就是將其索引的最后一列轉(zhuǎn)變成 DataFrame 對象的列索引,而剩下的索引則轉(zhuǎn)變成 DataFrame 對象的行索引。
# 獲取上圖所示的表格 grade_df6 = grade_df.groupby(['班級', '眼鏡', '性別'])['成績'].mean().unstack() # 查看grade_df6 grade_df67.數(shù)據(jù)可視化
1.導入中文字體
# 導入matplotlib庫的pyplot模塊 from matplotlib import pyplot as plt # 設置中文字體 plt.rcParams['font.family'] = ['Source Han Sans CN']? plt.rcParams['font.family'] 可以獲取 matplotlib 庫中的字體,'Source Han Sans CN' 指的是我們課程系統(tǒng)自帶的中文字體。plt.rcParams['font.family'] = ['Source Han Sans CN'] 意味著我們將課程中自帶的中文字體添加到了 matplotlib 的字體庫中。
? 而不同系統(tǒng)下自帶的中文字體是不一樣的,以下為Windows 和 Mac OS 系統(tǒng)下的常用中文字體。
2.單條折線圖
series.plot(kind='line', figsize=(7, 7), title='此人月考成績')? 繪制單條折線圖的代碼是:s.plot()。同樣的,這個方法有很多可以傳入的參數(shù),主要的是以下三個參數(shù):
3.多條折線圖
# 創(chuàng)建三位學生成績的df students_grade = pd.DataFrame({'李健': [80, 85, 89, 91, 88, 95],'王聰': [95, 92, 90, 85, 75, 80],'過凡': [90, 91, 92, 91, 90, 91]}, index=['2月', '3月', '4月', '5月', '6月', '7月']) # 繪制多條折線圖 students_grade.plot(kind='line', figsize=(7, 7), title='月考成績')多條折線圖的繪制方法是:df.plot()。它和單條折線圖相比,最大的區(qū)別就在于:多條折線圖是針對一個 DataFrame 對象來繪制的,而單條折線圖是針對一個 Series 對象來繪制的.df.plot() 默認會將每一列數(shù)據(jù)用 s.plot() 繪制成單條折線圖,然后合并到同一張圖上。而剛才提到的三個參數(shù):kind、figsize、title 以及補充給你的幾個參數(shù),df.plot() 都是可以沿用的,效果也相同。
4.餅圖
# 導入數(shù)據(jù) my_data = pd.read_csv('./工作/clean_data.csv', encoding='utf-8') # 查看my_data my_data # 獲取行業(yè)的頻率分布 profession = my_data['行業(yè)'].value_counts()/my_data['行業(yè)'].value_counts().sum() # 繪制行業(yè)頻率分布的餅圖 profession.plot(kind='pie', autopct='%.2f%%', figsize=(7, 7), title='行業(yè)頻率分布圖', label='')5.條形圖
# 獲取崗位的頻率分布 position = my_data['崗位'].value_counts()/my_data['崗位'].value_counts().sum() # 繪制崗位的頻率分布條形圖 position.plot(kind='bar', figsize=(13, 6), title='崗位頻率分布條形圖')(三)matplotlib
0.數(shù)據(jù)可視化工具
? 首先介紹一下數(shù)據(jù)可視化的主流工具:
? Tableau 和 PowerBI 均為數(shù)據(jù)可視化工具的頭部選手,它們的功能比較接近,主要是制作數(shù)據(jù)看板。其中 Tableau 偏商業(yè)分析,可視化偏標準化,需要付費。PowerBI 適合所有類型的用戶,可視化更具定制化,但是自定義和共享儀表板需要付費。而 Python 作為一種編程語言,通過調(diào)用第三方可視化庫作圖,覆蓋的圖表種類很多,定制化非常強,并且免費。再加上 Python 基本涵蓋了數(shù)據(jù)分析的整個流程:從數(shù)據(jù)處理到數(shù)據(jù)分析,再到數(shù)據(jù)展現(xiàn)??梢哉f是行云流水,一氣呵成。
? 在 Python 中有幾個常用的第三方可視化庫:pandas、matplotlib 以及 seaborn。
? 更傾向于推薦 matplotlib 庫,主要原因是:
1)matplotlib 庫相較于 pandas 繪圖以及 seaborn 繪圖工具更為底層,因此,matplotlib庫中的繪圖函數(shù)、參數(shù)相對更多,我們可以根據(jù)自己的風格自由選擇。
2)從應用范圍上來看,在 python 數(shù)據(jù)分析領域,matplotlib 庫是與 numpy 庫、pandas 庫并駕齊驅(qū)的三庫之一,被稱作 python 數(shù)據(jù)分析的“三劍客”,由此可見其應用范圍之廣。
1.導入庫
from matplotlib import pyplot as plt2.畫布的生成與保存
? 生成畫布用到的是 pyplot 模塊下的 figure 函數(shù),即 plt.figure()。其中的參數(shù) figsize 可以控制畫布的長和寬,一般用元組的形式進行賦值。
# 生成畫布,并設置畫布的大小 plt.figure(figsize=(6, 6))? 輸出結(jié)果<Figure size 432x432 with 0 Axes>表示生成了一個空白的畫布對象。畫布大小為 6 英寸x6 英寸,默認分辨率為 72 像素/英寸,所以像素為 432x432。
? 如果要將 jupyter 沙盒中生成的圖形保存到本地,可以用 plt.savefig()對畫布進行保存,這里只需要設置它的路徑參數(shù)。
# 前面已經(jīng)作完圖了哈 # 保存畫布,并設置保存路徑 plt.savefig('./工作/各月總訂單量趨勢圖.png')3.設置x/y坐標值
1.直接用列表創(chuàng)建series對象
? x 是指坐標點的橫坐標(簡稱 x 坐標值),y 是指坐標點的縱坐標(簡稱 y 坐標值),它們均為可迭代對象,你可以理解為有序的元素序列,比如 x = (x1, x2, x3, ……, xn),y = (y1, y2, y3, ……, yn)。
? 這里以 Series 對象為例設置 x/y 坐標值。
# 設置 x/y 坐標值 x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度']) y = pd.Series([160, 200, 180, 155])2.讀取已有的series對象
# 設置 x 坐標值 x=series.index # 設置 y 坐標值 y=series.values4.繪制圖表
1.折線圖
# 生成畫布,并設置畫布的大小 plt.figure(figsize=(6, 6)) # 設置 x/y 坐標值 x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度']) y = pd.Series([59, 70, 68, 56])# 繪制折線圖,并調(diào)整線條顏色為湖藍色 plt.plot(x, y, color='dodgerblue')相關(guān)常用參數(shù):
matplotlib相關(guān)顏色:
? 參數(shù) marker 可以設置數(shù)據(jù)標記點的形狀,有點、圓、加號等,常見為字符串類型,有以下這些:
2.柱狀圖
? 和折線圖一樣,繪制柱狀圖也需要設置 x/y 坐標值,不同的是柱狀圖繪圖函數(shù) plt.bar()的參數(shù)是 x 和 height,height 表示柱子的高,對應 y 坐標值。
# 生成畫布,并設置畫布的大小 plt.figure(figsize=(6, 6)) # 設置 x/y 坐標值 x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度']) y = pd.Series([59, 70, 68, 56])# 繪制柱狀圖,并調(diào)整顏色為深橘色,透明度為 60% plt.bar(x, height=y, color='darkorange', alpha=0.6)3.餅圖
? 餅圖和折線圖、柱狀圖在圖像特征方面差異蠻大的,它只用到了 x 表示餅圖中各個扇形面積的大小。
# 生成畫布,并設置畫布的大小 plt.figure(figsize=(6,6)) # 設置扇形面積值(x值) x=pd.Series([59,70,68,56]) # 設置百分比小數(shù)的位數(shù):保留百分比小數(shù)點后兩位 autopct='%.2f%%' # 設置百分比字體大小和顏色 textprops={'fontsize':12,'color':'black'} # 設置餅圖的“爆炸效果”:讓扇形遠離圓心 explode=[0.1,0,0,0] # 設置不同扇形的顏色 colors=['cornflowerblue', 'salmon', 'yellowgreen', 'orange'] # 繪制餅圖 plt.pie(x,autopct=autopct,textpros=textpros,explode=explode,colors=colors)?
5.設置圖表標題
? 圖表標題默認放在圖表頂部,向讀者傳遞圖表的名稱。設置圖表標題用的是 plt.title()函數(shù),包含兩個參數(shù):第一個參數(shù) label 設置圖表的標題名,常見為字符串類型;第二個參數(shù) fontsize 設置標題的字體大小,需要向它傳入一個代表字體大小的數(shù)值。
# 生成畫布,并設置畫布的大小 plt.figure(figsize=(6, 6)) # 繪制柱狀圖 plt.bar(x, height=y, color='darkorange', alpha=0.6)# 設置圖表標題名及字體大小 plt.title('2020年各季度研發(fā)費用分布圖', fontsize=20)? 稍稍拓展一下,如果想設置更豐富的字體樣式,可以用 fontdict 參數(shù)代替 fontsize。fontdict 是一個包含許多參數(shù)的字典,以思源黑體字體為例,詳見以下表格👇。
# 生成畫布,并設置畫布的大小 plt.figure(figsize=(6, 6)) # 繪制柱狀圖 plt.bar(x, height=y, color='darkorange', alpha=0.6)# 設置圖表標題名及字體大小 plt.title('2020年各季度研發(fā)費用分布圖', fontdict={'family': 'Source Han Sans CN', 'color': 'blue', 'weight': 'bold', 'size': 16})6.設置坐標軸
? 主要考慮坐標軸刻度和坐標軸標題:
1.坐標軸刻度
? 設置 x、y 軸刻度的函數(shù)分別是 plt.xticks()和 plt.yticks()。調(diào)用這兩個函數(shù),就可以根據(jù) x、y 坐標值自動生成 x、y 軸刻度字體大小。
# 生成畫布,并設置畫布的大小 plt.figure(figsize=(6, 6)) # 設置 x/y 坐標值 x = pd.Series(['第一季度', '第二季度', '第三季度', '第四季度']) y = pd.Series([59, 70, 68, 56]) # 繪制柱狀圖 plt.bar(x, height=y, color='darkorange', alpha=0.6)# 設置坐標軸的刻度字體大小 plt.xticks(fontsize=12) plt.yticks(fontsize=12)? 當然,坐標軸刻度是可以自定義的,比如調(diào)整刻度的間隔、標簽名稱等。不過在此先不作過多贅述。
2.坐標軸標題
# 設置坐標軸的標題名及字體大小 plt.xlabel('季度', fontsize=15) plt.ylabel('研發(fā)費用(百萬元)', fontsize=15)? 拓展一下,在上述函數(shù)中還可以添加參數(shù) ha和va,設置標題文本的對齊方式:與水平對齊方式有關(guān)的參數(shù) ha,可選’left’、‘right’、'center’等,以及與垂直對齊方式有關(guān)的參數(shù) va,可選 ‘center’、 ‘top’、 ‘bottom’、 'baseline’等。
7.設置圖例
? 設置圖例用到 plt.legend()函數(shù),其中的參數(shù)labels表示圖例名稱,對應圖中的多個條件,通常傳入可迭代對象,比如列表、Series 對象等。
# 設置圖例為'研發(fā)費用變化'、'研發(fā)費用分布' plt.legend(['研發(fā)費用變化','研發(fā)費用分布'])8.設置數(shù)據(jù)標簽
? 數(shù)據(jù)標簽是指坐標點上方顯示的標簽,用于呈現(xiàn)每個坐標點的數(shù)據(jù)信息。添加數(shù)據(jù)標簽用到 plt.text()函數(shù),它有幾個參數(shù),分別是 x、y、s、ha、va 以及 fontsize。
? 調(diào)用 plt.text()函數(shù)可以在圖表的指定位置添加文本,但是每次只能添加一個。這里需要重點強調(diào) x、y 的用法,x、y 表示所添加文本的位置,受到函數(shù)本身的屬性限制,常見為數(shù)值或者字符串類型,這與繪圖函數(shù)中 x、y 可以傳入可迭代對象有很大的差異。
? 更為簡潔的代碼可以借助 zip()函數(shù)實現(xiàn)??梢詫?zip()函數(shù)理解為拉鏈,x=(x1, x2, x3,……, xn)為拉鏈的左邊,y=(y1, y2, y3,……, yn)為拉鏈的右邊,經(jīng)過 zip()函數(shù),就合并為(x1, y1), (x2, y2), (x3, y3),……,(xn, yn)。
? zip()函數(shù)可以從 x、y 元素序列中依次取出元素,按照順序進行一對一匹配。
# 設置數(shù)據(jù)標簽 for a, b in zip(x, y):plt.text(a, b, b, ha='center', va='bottom', fontsize=12)9.總結(jié)
? 其實有的時候要注意的點是,每個要傳進去的參數(shù)是什么格式,比如數(shù)字、字符串、列表、字典,這些一定要搞清楚了。我覺得這一切都和維度有關(guān),比如列表,它是在同一個維度進行縱向延申的,只要封在了一個列表里,它就是一個類型的東西,你加進去很多個都是同類型的具體對應不同而已;但是字典就用在多個維度,比如每一個東西對應了一個什么或幾個什么。所以我感覺,很多時候,用列表是為了強調(diào)它們的并列性,防止被認為是多個維度的東西;而用字典傳入是因為確實是同一事物的多個維度,所以只能用字典傳入。
階段小結(jié):
(四)關(guān)聯(lián)分析與Apriori算法
1.關(guān)聯(lián)分析
? 關(guān)聯(lián)分析,是一門分析技術(shù),用于發(fā)現(xiàn)大量數(shù)據(jù)中,各組數(shù)據(jù)之間的聯(lián)系。
? 交易中的不同物品可稱為一個項。所以,這4條交易記錄,一共含有4個項(商品類目):“薯條”,“可樂”,“奶茶”,“漢堡”。0個或多個項的集合,可稱為一個項集,一般用{X}的形式表示項集,k 個項組成的項集,叫 k 項集。
1.支持度
? **支持度(Support)**可以表示項集在事務中出現(xiàn)的概率(頻率),你也可以理解成顧客對某一個項集的“支持程度”。
? {X}的支持度 = {X}在事務中出現(xiàn)的次數(shù) / 事務總數(shù)。
? 需要人為地設定一個支持度,名為最小支持度,用于篩掉那些不符合需求的項集。被留下來的項集(≥ 最小支持度),被稱為頻繁項集。
? 有了頻繁項集,就可以生產(chǎn)關(guān)聯(lián)規(guī)則了。關(guān)聯(lián)分析是探索數(shù)據(jù)之間聯(lián)系的技術(shù),而數(shù)據(jù)之間的聯(lián)系,我們用關(guān)聯(lián)規(guī)則來表示,表達式為:{X}→{Y}(X 和 Y 之間不存在相同項)。規(guī)則有順序之分,為了方便描述,我們把規(guī)則前面的項集叫前件,把規(guī)則后面的項集叫后件。但是,怎么知道這種聯(lián)系是否可靠?如果可靠,到底有多可靠?哪個更可靠?
#####2.置信度
? 置信度(Confidence)可用于衡量關(guān)聯(lián)規(guī)則的可靠程度,表示在前件出現(xiàn)的情況下,后件出現(xiàn)的概率。一般來說,概率越高,規(guī)則的可靠性越強。
? 關(guān)聯(lián)規(guī)則{X}→{Y}的置信度 = {X,Y}的支持度 / {X}的支持度。
? 同為關(guān)聯(lián)規(guī)則,可靠程度有“強”有“弱”。在實際業(yè)務中,也需要人為地設定置信度,名為最小置信度,用于篩掉一些不符合需求的關(guān)聯(lián)規(guī)則。被留下來的關(guān)聯(lián)規(guī)則( ≥ 最小置信度),叫做強關(guān)聯(lián)規(guī)則。
? 眾所周知,在自然界,不同物種之間,不僅有“互惠互利”的合作關(guān)系,也有“勢不兩立”的競爭關(guān)系。關(guān)聯(lián)規(guī)則也一樣,既有促進關(guān)系,也有抑制關(guān)系。因而,還需引入**提升度(Lift)**對它們進行判斷。
3.提升度
? {X}→{Y}的提升度 = {X}→{Y}的置信度 / {Y}的支持度,意思是評估 X 的出現(xiàn),對 Y 出現(xiàn)的影響有多大。
總結(jié):
2.Apriori算法
? Apriori是用于挖掘出數(shù)據(jù)背后的關(guān)聯(lián)規(guī)則的一種算法,以下簡寫為 Apr 算法,它的流程可分為兩步(簡單了解它的運作原理即可,無需深究):
1.確定最小支持度和最小置信度
? 判斷它們是否“合適”的感覺很微妙,沒有特定的標準答案
? 其實總結(jié)起來就一個字:試。一開始設定的最小支持度和置信度和理想狀態(tài)有一定偏差也沒關(guān)系,后續(xù)再慢慢調(diào)整。
#####2.找出頻繁項集和強關(guān)聯(lián)規(guī)則
######1.頻繁項集
? 這一步,Apr 的算法主要依賴兩個性質(zhì):
1)一個項集如若是頻繁的,那它的非空子集也一定是頻繁的。假如購買{薯條,奶茶}的概率都很高,那購買{薯條}或{奶茶}的概率肯定也很高;
2)一個項集如若是非頻繁的,那包含該項集的項集也一定是非頻繁的。假設購買{薯條}的次數(shù)少,那購買{薯條,奶茶}的次數(shù)肯定也少。
? 在 Apr 算法出現(xiàn)之前,要找出所有的頻繁項集,就得先枚舉所有的項集,計算它們的支持度,然后和最小支持度(0.2)進行對比,篩選出頻繁項集。
? 但 Apr 算法不一樣,它對錯誤的“道路”進行了提前預判。一旦找到某個不滿足條件的“非頻繁項集”,包含該集合的其他項集不需要計算,更不用對比,通通繞開。
? 憑借新生成的頻繁項集,就可以開始“制造”關(guān)聯(lián)規(guī)則了。
2.關(guān)聯(lián)規(guī)則
? 值得注意的是,因為頻繁 1 項集只有一個項,無法構(gòu)成具有指導意義的關(guān)聯(lián)關(guān)系(≥ 2 項),可直接忽略。
? Apr 算法會先產(chǎn)生一系列后件項數(shù)為1的關(guān)聯(lián)規(guī)則,與最小置信度進行比較,得到一部分強關(guān)聯(lián)規(guī)則。然后,頻繁項集繼續(xù)生成后件項數(shù)為2的關(guān)聯(lián)規(guī)則,再對它們的置信度進行比較,又收獲一批強關(guān)聯(lián)規(guī)則。當無法從剩下的頻繁項集中生成新的關(guān)聯(lián)規(guī)則時,該過程就結(jié)束了。
? 關(guān)聯(lián)規(guī)則的支持度,和構(gòu)建規(guī)則的頻繁項集的支持度一致。
? 若是這些強關(guān)聯(lián)規(guī)則正好是你想要的,那就進一步計算它們的提升度。相反,若是你對篩選出來的強關(guān)聯(lián)規(guī)則不滿意,那我們就得重新調(diào)整最小支持度和最小置信度,再計算一次。
? 盡管 Apr 算法已經(jīng)對原始的關(guān)聯(lián)分析做了優(yōu)化,但手動計算依然繁瑣,特別是當我想要調(diào)整最小支持度或者最小置信度的時候。如果能把 Apr 算法的計算流程抽象成函數(shù),將最小支持度、最小置信度和最小提升度設置成參數(shù),通過調(diào)整參數(shù)來查看關(guān)聯(lián)規(guī)則,想怎么調(diào)就怎么調(diào)就好了。實際上,Python 早已可以實現(xiàn)。
3. Python 調(diào)用 apriori 函數(shù)
? 提供這一便利的是apyori模塊下的apriori函數(shù), apyori模塊屬于 Python 的第三方模塊。
from apyori import apriori orders = [['薯條', '可樂'], ['薯條', '可樂', '奶茶'], ['漢堡', '薯條', '可樂'], ['漢堡', '可樂']] results=apriori(orders,min_support=0.2,min_confidence=0.7) results? 這段代碼返回的是一串<generator object apriori at 0x7fa21646ec50>,<generator>是一個生成器對象,它是一種用于節(jié)省空間的運算機制,可以通過循環(huán)遍歷的形式對它里面的數(shù)據(jù)進行訪問:
for result in results:print(result)? 得到的是一堆略顯復雜,但實際具有很強結(jié)構(gòu)性的東西:(每個都不過是自定義元組內(nèi)嵌套列表又在內(nèi)嵌套了一層自定義元組罷遼,逐層提取然后把各個有意義的數(shù)據(jù)轉(zhuǎn)化成所需的數(shù)據(jù)結(jié)構(gòu)就好)
RelationRecord(items=frozenset({'可樂'}), support=1.0, ordered_statistics=[OrderedStatistic(items_base=frozenset(), items_add=frozenset({'可樂'}), confidence=1.0, lift=1.0)]) RelationRecord(items=frozenset({'薯條'}), support=0.75, ordered_statistics=[OrderedStatistic(items_base=frozenset(), items_add=frozenset({'薯條'}), confidence=0.75, lift=1.0)]) RelationRecord(items=frozenset({'奶茶', '可樂'}), support=0.25, ordered_statistics=[OrderedStatistic(items_base=frozenset({'奶茶'}), items_add=frozenset({'可樂'}), confidence=1.0, lift=1.0)]) RelationRecord(items=frozenset({'漢堡', '可樂'}), support=0.5, ordered_statistics=[OrderedStatistic(items_base=frozenset({'漢堡'}), items_add=frozenset({'可樂'}), confidence=1.0, lift=1.0)]) RelationRecord(items=frozenset({'薯條', '可樂'}), support=0.75, ordered_statistics=[OrderedStatistic(items_base=frozenset(), items_add=frozenset({'薯條', '可樂'}), confidence=0.75, lift=1.0), OrderedStatistic(items_base=frozenset({'可樂'}), items_add=frozenset({'薯條'}), confidence=0.75, lift=1.0), OrderedStatistic(items_base=frozenset({'薯條'}), items_add=frozenset({'可樂'}), confidence=1.0, lift=1.0)]) RelationRecord(items=frozenset({'薯條', '奶茶'}), support=0.25, ordered_statistics=[OrderedStatistic(items_base=frozenset({'奶茶'}), items_add=frozenset({'薯條'}), confidence=1.0, lift=1.3333333333333333)]) RelationRecord(items=frozenset({'薯條', '奶茶', '可樂'}), support=0.25, ordered_statistics=[OrderedStatistic(items_base=frozenset({'奶茶'}), items_add=frozenset({'薯條', '可樂'}), confidence=1.0, lift=1.3333333333333333), OrderedStatistic(items_base=frozenset({'奶茶', '可樂'}), items_add=frozenset({'薯條'}), confidence=1.0, lift=1.3333333333333333), OrderedStatistic(items_base=frozenset({'薯條', '奶茶'}), items_add=frozenset({'可樂'}), confidence=1.0, lift=1.0)]) RelationRecord(items=frozenset({'薯條', '漢堡', '可樂'}), support=0.25, ordered_statistics=[OrderedStatistic(items_base=frozenset({'薯條', '漢堡'}), items_add=frozenset({'可樂'}), confidence=1.0, lift=1.0)])? 先來簡單了解一下幾個陌生的數(shù)據(jù)類型:
-
RelationRecord(關(guān)系記錄)和 OrderedStatistic(有序的統(tǒng)計數(shù)據(jù))是模塊作者自定義的命名元組(namedtuple),可以理解成一種通過名稱訪問的元組。
-
frozenset是一種不可變的集合,使用list()函數(shù),可以將它轉(zhuǎn)換成我們熟悉的列表形態(tài)。
然后再來了解一下數(shù)據(jù)的結(jié)構(gòu):
-
一條“關(guān)系記錄”(RelationRecord),包含了頻繁項集的基本信息:頻繁項集items,支持度support和統(tǒng)計列表ordered_statistics。
-
一條“統(tǒng)計列表”(ordered_statistics),包含了該頻繁項集下構(gòu)建的所有強關(guān)聯(lián)規(guī)則OrderedStatistic。
-
一條“強關(guān)聯(lián)規(guī)則”(OrderedStatistic),包含了該規(guī)則的基本信息:前件items_base,后件items_add,置信度confidence,提升度lift。
? 雖然這樣一梳理,數(shù)據(jù)清晰了不少,但這樣的展現(xiàn)形式還是太“反人類”了,需要進一步抽取關(guān)鍵信息。抽取的重點,是由前件和后件組成的強關(guān)聯(lián)規(guī)則,以及它們的支持度、置信度、提升度。若找到前件為空集的強關(guān)聯(lián)規(guī)則,那么,這條規(guī)則其實沒有什么現(xiàn)實意義,可直接刪除。
(五)RFM模型
1.模型簡介
1.原理
1)R(Recency):最近一次消費時間間隔,指用戶最近一次消費時間距離現(xiàn)在的時間間隔,上一次消費時間離現(xiàn)在越近,再次消費的幾率越大。即 R 值越小,用戶的活躍度越大,用戶的價值就越高;
2)F(Frequency):消費頻率,指用戶一段時間內(nèi)消費了多少次,購買頻率越高,說明用戶對品牌產(chǎn)生一定的信任和情感維系。即 F 值越大,用戶的忠誠度就越大,用戶的價值就越高;
3)M(Monetary):消費金額,指用戶一段時間內(nèi)的消費金額,消費金額越高,說明用戶對產(chǎn)品的購買力越大。即 M 值越大,用戶的購買力就越大,用戶的價值就越高。
? 這三項數(shù)據(jù)作為衡量客戶價值和客戶創(chuàng)利能力的重要工具和手段,也是 RFM 模型的三個重要指標。
2.作用
? RFM 模型多用于精細化運營服務。
? 如果根據(jù) RFM 模型將用戶細分為 8 類,還能進一步對不同價值的用戶使用不同的運營策略,獲取并保留關(guān)鍵性用戶,針對價值高的客戶制定促銷策略。
2.RFM模型構(gòu)建流程
1.計算R、F、M的值
? 得到 R、F、M 這 3 個指標,一般需要的信息有:用戶名稱/用戶 ID、消費記錄(如消費時間、消費金額)。
#####2.根據(jù) RFM 的閾值,對用戶進行分類
? 獲得閾值,可以對 RFM 各值采取分區(qū)域評分,再計算各值平均數(shù)的方式,該方式會分為三個步驟:
1)給 R、F、M 各值按價值劃分打分區(qū)間(如何定義打分的范圍,需要結(jié)合具體的業(yè)務來調(diào)整)
2)計算價值的平均值
3)用戶分類(將兩個用戶的 RFM 值與各值的平均值進行對比。)
? 如果一行里的 R 值打分大于平均值,就標記該行的 R 值打分為“高”,反之標記為“低”。F、M 值亦是同理。
? 然后,再將標記好的 RFM 高低值與用戶分類規(guī)則表進行對比,可以得出用戶屬于哪種類別。
(六)NumPy
1.numpy簡介
? NumPy 是一個開源的 Python 科學計算基礎庫。
1)在性能方面:NumPy 的計算操作由預編譯好的 C 代碼快速執(zhí)行。所以比之 Python,它的運算速度常常更快。
2)在存儲方面:NumPy 同樣也設計了一個更好的存儲結(jié)構(gòu)來提高計算效率。
? 第一板塊,可以說是最基礎的板塊:ndarray 數(shù)組。
? 第二個板塊:ufunc 通用函數(shù)。就像一套能處理數(shù)組的工具,它能對 NumPy 數(shù)組中的元素逐個進行操作。和 Python 內(nèi)置的 math 模塊類似,它主要用于實現(xiàn)一些較為基礎的數(shù)組運算,例如求和、求平方根等。
? 第三個板塊是用于科學計算的子模塊包。這些子模塊包內(nèi)包括隨機數(shù)包、線性代數(shù)包,矩陣包等內(nèi)容。這些子模塊包,就像各種能處理數(shù)組的工具包。在這些工具包內(nèi)還有各式各樣的工具來幫助你完成復雜的科學計算。
導入numpy庫:
import numpy as np2.ndarray數(shù)組
1.n維數(shù)據(jù)
① 一維
? 一維數(shù)據(jù)一般由線性方式組織的數(shù)據(jù)構(gòu)成。
② 二維
? 二維數(shù)據(jù)是由多個一維數(shù)據(jù)構(gòu)成的數(shù)據(jù),它是一維數(shù)據(jù)的組合。
? 平時常見的表格同樣也是由多行一維數(shù)據(jù)堆疊而成的。它也是一種典型的二維數(shù)據(jù)。
③三維
? 三維數(shù)據(jù)是由一維數(shù)據(jù)或二維數(shù)據(jù)在一個新的維度上擴展而成的。
? 同為二維數(shù)據(jù)的表格在時間維度做上拓展后,也可以變成三維數(shù)據(jù)。
2.創(chuàng)建 ndarray
np.array(列表/元組)傳入一維列表
# 創(chuàng)建一維的列表 list_1 list_1 = [1, 2, 3]# 創(chuàng)建數(shù)組 array_1 array_1 = np.array(list_1) # 查看數(shù)組 array_1 array_1# array([1, 2, 3])傳入二維列表
# 創(chuàng)建二維的列表 list_2 list_2 = [[0, 0, 0],[10, 10, 10],[20, 20, 20],[30, 30, 30]]# 創(chuàng)建數(shù)組 array_2 array_2 = np.array(list_2) # 查看數(shù)組 array_2 array_2#array([[ 0, 0, 0], # [10, 10, 10], # [20, 20, 20], # [30, 30, 30]])傳入三維列表
# 創(chuàng)建三維的列表 list_3 list_3 = [[[0, 0, 0],[10, 10, 10],[20, 20, 20],[30, 30, 30]],[[0, 0, 0],[10, 10, 10],[20, 20, 20],[30, 30, 30]],[[0, 0, 0],[10, 10, 10],[20, 20, 20],[30, 30, 30]]]# 創(chuàng)建數(shù)組 array_3 array_3 = np.array(list_3) # 查看數(shù)組 array_3 array_3#array([[[ 0, 0, 0], # [10, 10, 10], # [20, 20, 20], # [30, 30, 30]],# [[ 0, 0, 0], # [10, 10, 10], # [20, 20, 20], # [30, 30, 30]],# [[ 0, 0, 0], # [10, 10, 10], # [20, 20, 20], # [30, 30, 30]]])? 除了 array() 方法,NumPy 還提供了其他辦法來創(chuàng)建數(shù)組,有需要時,可以再補充學習。以下表格內(nèi)提到的方法各有優(yōu)劣。而在使用時,我們可以根據(jù)實際情況來選擇對應的方法創(chuàng)建數(shù)組。
? 補充一點,不同于 Python ,ndarray 數(shù)組要求所有的元素類型相同。所以,通過 array() 方法創(chuàng)建數(shù)組時,傳入的數(shù)據(jù)參數(shù)需要統(tǒng)一其內(nèi)部元素的數(shù)據(jù)類型。
3.ndarray的特征
1.維度(ndim.shape.size)
①相關(guān)概念
? 先明確兩個概念:軸(axis)、秩(rank)
1)軸(axis)簡單來說就是維度。在實際使用時,我們會用從 0 開始的數(shù)字表示不同的維度,像:axis = 0、axis = 1、axis = 2 等。
2)秩(rank)比較好理解,就是指維度的數(shù)量。
數(shù)組每次新增的軸,也就是最外圍的維度,都為 0。
②查看屬性
? 3 個可用于查看數(shù)組維度信息的屬性,它們分別是:shape、ndim、size。
1)shape 屬性表示數(shù)組的形狀,即各個維度上的數(shù)據(jù)長度。當你調(diào)用它時,會返回一個元組作為結(jié)果。
# 查看數(shù)組 array_2 array_2#array([[ 0, 0, 0], # [10, 10, 10], # [20, 20, 20], # [30, 30, 30]])# 調(diào)用屬性 shape,查看數(shù)組形狀 array_2.shape#(4, 3)? 一定要注意,這個排列順序是從axis=0開始的,但是axis=0對應的始終是最新加進去的那一個維度(上圖其實表達的已經(jīng)很直觀了)。如果從它形式上的格式來理解,就是從最外面一層中括號開始剝,最外面第一層剝開有幾個并列的,它在axis=0上的長度就是幾,再往里剝,axis逐漸變大。
2)ndim 屬性能表示軸/維度的數(shù)量,調(diào)用 ndim 屬性后,代碼會以整數(shù)形式返回數(shù)組的維度數(shù)量。
# 查看數(shù)組 array_2 array_2#array([[ 0, 0, 0], # [10, 10, 10], # [20, 20, 20], # [30, 30, 30]])# 調(diào)用屬性 ndim,查看數(shù)組的維度數(shù)量 array_2.ndim#2? 其實可以說,size屬性對應的那個數(shù)字,就是shape屬性里的幾個數(shù)字相乘。
小總結(jié):
2.索引
? 同 Python 的列表類似,ndarray 數(shù)組也有能對元素進行索引操作的特點。索引操作用于獲取數(shù)組中特定位置的元素。
①普通索引
? 一維數(shù)組中,單個元素的索引會與列表的索引很相似。數(shù)組中的元素會有從 0 開始的數(shù)字作為其索引下標。
array_1[索引值]? 多維數(shù)組中的單個元素的索引,其實也和列表的嵌套索引很類似。在每條軸的方向上,我們分別取一個索引值,然后用逗號分割即可。
array_1[索引值0,索引值1] array_1[索引值0,索引值1,索引值2]? 不過還是要注意,這個順序還是按照axis從0到n的順序從左到右的。也就是說,依然是比低一階所新增的那個維度是0,或者說是最外面的那一層括號是axis=0。
②布爾索引
# 打印布爾數(shù)組方便查看 print(array_2 < 20)#[[ True True True] # [ True True True] # [False False False] # [False False False]]# 用布爾數(shù)組索引數(shù)組 array_2 中的特定元素 array_2[array_2 < 20]#array([ 0, 0, 0, 10, 10, 10])? 要注意嗷,這里使用布爾索引就和位置毫無關(guān)系啦!它只取決于各位置上元素是否滿足條件,而與位置坐標無關(guān),賦值True/False以后,其值為True的會被提取出來。(其實跟前面那個pd里對df的操作挺相似的。)
③切片
? 切片是獲取數(shù)組元素子集的過程。它和列表的切片有點類似,簡單來說,就是取出兩個索引中間夾著的元素。
? 一維數(shù)組:
ndarray[起點索引值: 終點索引值(取值時不包括): 步長]? n維數(shù)組就是中間用逗號隔開了,還是要注意誰是axis=0就好。
#利用索引配合切片來取該數(shù)組中所有第二行的元素 #array([[[0.2, 0.2, 0.2], # [0.3, 0.3, 0.3], # [0.4, 0.4, 0.4], # [0.5, 0.5, 0.5]],# [[0.2, 0.2, 0.2], # [0.3, 0.3, 0.3], # [0.4, 0.4, 0.4], # [0.5, 0.5, 0.5]],# [[0.2, 0.2, 0.2], # [0.3, 0.3, 0.3], # [0.4, 0.4, 0.4], # [0.5, 0.5, 0.5]]])# 切片取數(shù)組 array_b 中的目標元素 array_b[:, 1, :]方法:只要想象那個空間圖就好了。
3.元素的數(shù)據(jù)類型
在 ndarray 數(shù)組中,常見的元素數(shù)據(jù)類型有:
? 不同于 Python,這里整數(shù)、浮點數(shù)等都被區(qū)分為了各種位的長度。位的長度這個概念涉及一些計算機底層的理論,我們這里先暫時不去理解它。只需要知道之所以 NumPy 要如此精細管理 ndarray 的元素類型,是因為這樣有助于它合理使用存儲空間并優(yōu)化性能。
4.向量運算
1)兩個數(shù)組 a 和 b 形狀相同,即滿足a.shape == b.shape時。此時,兩個數(shù)組在加減乘除后,它們內(nèi)部對應位置的元素會一一對應做加減乘除。
2)數(shù)組與一個形狀不一樣的數(shù)據(jù)進行運算時。但在這種情況下進行運算,不是隨便兩個形狀不一樣的數(shù)組都能進行運算的。
? 關(guān)于這一點,NumPy 有一套計算規(guī)則叫“廣播”(Broadcast)。把官方說明翻譯過來就是:兩個形狀不同數(shù)組間運算時,它們對應維度的長度必須相同,或者其中一方為 1(這是和常規(guī)計算好像不太一樣的!!),才可以運算成功,否則就會報錯。
4.總結(jié)
(七)Seaborn
1.seaborn概述
1.介紹
1)Relational(關(guān)系)可以用來展示定量數(shù)據(jù)之間關(guān)系的趨勢,如離散程度或者數(shù)據(jù)隨時間變化的情況。
2)Distribution(分布)可以用來展示定量數(shù)據(jù)的分布信息,比如頻數(shù)分布情況,數(shù)據(jù)的形態(tài)等。
3)Categorical(分類)可以用來展示定性數(shù)據(jù)之間的分布或關(guān)系之類的信息,比如不同類別數(shù)據(jù)的大小,分布情況等。
? 其他的,如:Regression(回歸) 可用于畫出線性回歸圖形,Matrix(矩陣)可以畫熱力圖和聚類圖,Multiple(復合)可以用多個子圖或者二元圖實現(xiàn)不同條件之間的關(guān)系、頻數(shù)分布等功能。
2.導入&中文字體調(diào)整
import seaborn as sns import matplotlib.pyplot as plt # 設置中文字體(這一段在前面已經(jīng)比較具體的整理過了) plt.rcParams['font.sans-serif'] = ['Source Han Sans CN']2.Relational 中的常見圖形
1.散點圖
1.介紹
? 散點圖可以比較直觀地觀察變量 x 與變量 y 之間的相互影響程度。對于那些變量之間存在密切關(guān)系,但是這些關(guān)系又不像數(shù)學或物理公式那樣能夠精確表達的,散點圖是一種很好的圖形工具。
? 在散點圖中,如果變量之間不存在線性關(guān)系,則表現(xiàn)為隨機分布的離散的點;如果變量間存在某種線性關(guān)系,那么大部分的數(shù)據(jù)點就會相對密集并以某種形態(tài)呈現(xiàn)。
? 在觀察散點圖的時候,還有一個概念需要我們理解——離群點。當變量間存在某種線性關(guān)系時,大部分的數(shù)據(jù)點會表現(xiàn)出相對密集的形態(tài),但總有幾個不合群的數(shù)據(jù)點離集群較遠,我們可以稱這些點為離群點或異常點。
2.語法
? 官方文檔推薦我們使用 seaborn.relplot() 這個函數(shù)來畫散點圖,記憶的話很容易,relplot 其實是 Relational Plot(關(guān)系圖形)的縮寫,我們要畫的圖是散點圖,散點圖屬于關(guān)系圖形,腦中建立起這樣的聯(lián)系,就不用去死記硬背函數(shù)名了。seaborn.relplot() 的語法和常用參數(shù)如下圖所示:
? 其中,參數(shù) x、y 和 data 都是必選參數(shù),x 和 y 一般為連續(xù)數(shù)據(jù),可以理解為上面說的變量 x 和變量 y;data 指的是需要展示的數(shù)據(jù)集,推薦先把數(shù)據(jù)通過 pandas 讀取成 DataFrame 類型后再傳給參數(shù) data。
? 可選參數(shù)hue,通過圖中的不同顏色表示不同含義,可以讓我們在圖中添加一個維度。
? 可選參數(shù) size,它會根據(jù)傳入數(shù)據(jù)的大小在散點圖中生成大小不同的點。比如,我們把 ‘身高’ 傳給這個參數(shù),那么在生成的圖形中,身高越大,點也就越大,反之亦然。
? 可選參數(shù)style,它可以在某一維度上,用點的不同形狀區(qū)分數(shù)據(jù)。
? 還有一個可選參數(shù) kind,被我隱藏掉了,其值默認為 'scatter'(散點圖)。在畫散點圖時,可以不用寫這個參數(shù)。
import pandas as pd student_info=pd.read_csv('./source-data/學生信息.csv') sns.relplot(x='身高',y='體重',data=student_info,hue='性別',size='體重',style='班級')? 小tips:根據(jù)科學研究,人的眼睛對顏色比對形狀更敏感,因此,在做可視化時,我們可以優(yōu)先考慮使用顏色來區(qū)分不同的數(shù)據(jù)。
2.折線圖
? 折線圖也可以反映數(shù)據(jù)間的關(guān)系,只不過它一般使用時間維度作為 X 軸,數(shù)值維度作為 Y 軸。當我們想要了解某一維度在時間上的規(guī)律或者趨勢時,用折線圖是個比較不錯的選擇。relplot() 函數(shù)也是可以畫出折線圖的,基本的折線圖只需要在必選參數(shù)的基礎上,寫上我們剛才隱藏的參數(shù) kind='line' 即可。
population = pd.read_csv('./source-data/人口_sim.csv') sns.relplot(x='年份', y='年末總?cè)丝?萬人)', data=population, kind='line')3.Distribution中的常見圖形
? 本節(jié)將著重于直方圖的相關(guān)知識和語法,至于其他涉及較復雜統(tǒng)計知識的圖形,暫時先不講。
1.直方圖概念
? 直方圖用于展示定量數(shù)據(jù)的分布情況,我們可以通過直方圖來觀察數(shù)據(jù)分布的大體形狀,比如:數(shù)據(jù)分布是否對稱,是右偏還是左偏等。
? 如果數(shù)據(jù)分布大體對稱的話,圖形會呈現(xiàn)出中間高,兩邊低,左右近似對稱的特點,就像上圖中間所示形狀一樣。
? 如果數(shù)據(jù)的眾數(shù) < 中位數(shù) < 平均數(shù),那么分布大體就會呈現(xiàn)出右偏分布的情況,形狀上類似上圖左側(cè)部分。
? 如果數(shù)據(jù)的眾數(shù) > 中位數(shù) > 平均數(shù),那么分布大體就會呈現(xiàn)出左偏分布的情況,形狀上類似上圖右側(cè)部分。
2.直方圖語法
? 必選參數(shù) x 和 data,與之前學過的一樣。x 一般為連續(xù)數(shù)據(jù),data 指的是我們要展示的數(shù)據(jù)集。值得注意的是,在直方圖的函數(shù)中,少了必選參數(shù) y,這是直方圖定義造成的結(jié)果。
titanic_info = pd.read_csv('./source-data/泰坦尼克乘客信息.csv') titanic_infosns.displot(x='乘客年齡', data=titanic_info,hue='乘客性別' )4.Categorical中的常見圖形
? 我們今天只學習箱型圖的相關(guān)知識和對應語法。
1.箱型圖概念
? 箱型圖又稱盒須圖、盒式圖或箱線圖,它可以反映一組數(shù)據(jù)的分布特點,如分布是否對稱,是否存在異常值,但其更適合對多組數(shù)據(jù)(分類數(shù)據(jù))的分布特征進行比較。
? 當一個數(shù)據(jù)集同時包含分類變量和連續(xù)變量時,箱形圖可以提供連續(xù)變量隨著分類變量改變而變化的信息。它使用了5個關(guān)鍵數(shù)值對分布進行概括,即一組數(shù)據(jù)的上相鄰值、下相鄰值、第一四分位數(shù)、中位數(shù)和第三四分位數(shù)。至于數(shù)據(jù)集中的異常值,則會被繪制成單獨的點。
? 通過觀察箱型圖,我們可以直觀地了解到中位數(shù),上相鄰值和下相鄰值這幾個描述數(shù)據(jù)分布情況的關(guān)鍵值,也可以清晰地看到數(shù)據(jù)集中是否存在異常值。如下圖所示,假如中位數(shù)在箱子中間位置的話,就說明這些數(shù)據(jù)是對稱分布的;箱子的長短也能體現(xiàn)分布情況,箱子較長意味著分布比較分散,若箱子很短,則數(shù)據(jù)分布得較為集中。
2.箱型圖語法
? 值得注意的是,我們必須將控制圖形類別的參數(shù) kind 寫為 kind='box',這樣才能畫出最基本的箱型圖。kind 的其他值還可以是:‘strip’ 對應的分布散點圖,‘swarm’ 對應的分簇散點圖,‘violin’ 對應的小提琴圖,‘boxen’ 對應的增強箱型圖,‘point’ 對應的點圖,‘bar’ 對應的條形圖和 ‘count’ 對應的計數(shù)圖。
? 可以先將類型按照一定順序存在列表中,再將這個列表傳給參數(shù) order,這樣就可以讓類別按照一定順序從左到右依次排列了。
chart_df = pd.read_csv('./source-data/購物表.csv') chart_df.head() # 創(chuàng)建順序列表 order_list order_list=['配飾', '鞋子', '衣服', '日用品', '書籍', '食品'] # 將順序列表傳給參數(shù) order sns.catplot(x='類型', y='價格', data=chart_df, kind='box',order=order_list)總結(jié):
5.簡單介紹軸級和圖級
? 上面我們討論的所有圖形,是 Seaborn 根據(jù)統(tǒng)計學知識這一維度進行分類的。其實 Seaborn 對于圖形還有另一種分類的維度——是否將數(shù)據(jù)繪制到坐標軸上,按照此維度,Seaborn 的圖形還可以劃分為:axes-level(軸級) 和 figure-level(圖級)。我們剛才講過的所有函數(shù)(relplot()、displot() 和 catplot())其實都屬于 figure-level(圖級),這些函數(shù)都可以通過改變參數(shù)kind 的值來畫出不同的圖形。
? 簡單介紹散點圖、直方圖和箱型圖對應的 axes-level(軸級) 函數(shù):
6.可視化庫拓展
1.seaborn
可以繼續(xù)閱讀官方文檔學習,其文檔結(jié)構(gòu)十分清晰;
? 但是,Matplotlib 和 Seaborn 生成的圖形,多有一種科技論文或?qū)W術(shù)期刊的風格,看起來有點嚴肅,而且都是些靜態(tài)的圖片,沒法交互。
? 所以,再簡單介紹兩個可交互的可視化庫,有興趣的話可以自學。
2.Plotly
? Plotly 是著名的開源交互式繪圖工具。它包含眾多的圖形種類,支持統(tǒng)計、金融、地理、科技、三維繪圖等共計40余種交互式圖表的繪制。默認樣式生成的圖片如下所示,可以發(fā)現(xiàn),圖片中是有交互欄的,更棒的是,當鼠標移動到圖形上時,會顯示出具體的數(shù)值,這比 Seaborn 要方便很多。Plotly 畫出的圖形配色生動,支持交互,又在圖形上方添加了交互欄,總體來說,是一種比較優(yōu)秀的可視化庫。但其官方文檔略微復雜,且網(wǎng)上的中文資料較少,自學起來可能會有一定的難度。
3.Pyecharts
? Pyecharts是基于 Echarts 開發(fā)的一個用于生成 Echarts 圖表的類庫,同樣支持交互操作。Echarts 是百度開源的一個數(shù)據(jù)可視化 JS 庫,憑借著良好的交互性,精巧的圖表設計,得到了眾多開發(fā)者的認可。而Pyecharts,實際上就是 Echarts 與 Python 的對接,支持 30 多種圖表。更重要的是,Pyecharts 的官方文檔是由中文撰寫的,自學起來沒有什么障礙.
總結(jié):
總結(jié)
以上是生活随笔為你收集整理的python数据分析可视化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C罗111球成国家队历史射手王,破纪录的
- 下一篇: python大数据书籍推荐-大数据入门书