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