數(shù)據(jù)分組是對(duì)相同類別的數(shù)據(jù)進(jìn)行匯總,而數(shù)據(jù)透視表是通過對(duì)行或列的不同組合對(duì)數(shù)據(jù)進(jìn)行匯總,所使用的匯總方法有求和、計(jì)數(shù)、平均值、標(biāo)準(zhǔn)差等,本文使用Python對(duì)數(shù)據(jù)進(jìn)行數(shù)據(jù)分組和數(shù)據(jù)透視,下面一起來(lái)學(xué)習(xí)。 一、groupby分組這里首先導(dǎo)入pandas和datetime庫(kù),生成一個(gè)包含'用戶ID','日期','城市','年齡','性別','成交量'的DataFrame數(shù)據(jù)。 import pandas as pdimport datetime
groupby可以通過傳入需要分組的參數(shù)實(shí)現(xiàn)對(duì)數(shù)據(jù)的分組,參數(shù)可以是單列,也可以是多列,分組后可以對(duì)單列進(jìn)行函數(shù)處理,也可以對(duì)多列進(jìn)行函數(shù)處理。 #按照單列分組df.groupby('城市').count()
先篩選列再groupby與先groupby再篩選列得出來(lái)的結(jié)果是一樣的。 # 先篩選,然后groupby要加dfdf['成交量'].groupby([df['城市'],df['性別']]).sum() 如果先聚合,聚合列可以只寫列名,不加變量名,因?yàn)闆]有篩選某列前,可以直接搜索到列。
#先groupby()再寫列,列不用加dfdf.groupby(['城市','性別'])['成交量'].sum() #求和 使用unstack函數(shù),增加數(shù)據(jù)透視的效果。
as_index=False,會(huì)按從0開始的數(shù)據(jù)索引。 #分組鍵一般會(huì)作為分層索引,如果不想要,可以在group()中加上參數(shù):as_index=False,會(huì)按從0開始的數(shù)據(jù)索引df.groupby([df['城市'], df['性別']],as_index=False).sum() 先數(shù)據(jù)分組,然后做描述分析。
size顯示數(shù)據(jù)組分類的多少。 df.groupby('城市').size() 二、group by與agg的用法groupby與agg兩者可以結(jié)合使用,可以對(duì)單列或多列進(jìn)行單一或多個(gè)不同的聚合運(yùn)算, 常用聚合函數(shù)有count,sum,std等,直接用函數(shù)名加引號(hào)即可,如果有多個(gè)函數(shù)時(shí),可以用逗號(hào)隔開;
列表可以同時(shí)使用多個(gè)函數(shù),用逗號(hào)隔開。 # 列表可以同時(shí)使用多個(gè)函數(shù)df.groupby(['城市', '性別']).agg(['mean','std','sum','count']) reset_index用來(lái)重置索引。
用元組修改函數(shù)名。 # 可以用元組修改函數(shù)名df.groupby(['城市', '性別']).agg([('No.1', 'sum'), ('No.2', 'std')]) 可以對(duì)不同的列使用不同的函數(shù)進(jìn)行運(yùn)算。
三、apply與agg的用法apply與agg相同點(diǎn):都可以對(duì)分組后的結(jié)果進(jìn)行運(yùn)算; apply與agg不同點(diǎn):agg只能對(duì)單列,apply可以對(duì)多列進(jìn)行;apply可以使用匿名函數(shù),agg不可以使用匿名函數(shù)。 #首先定義一個(gè)top函數(shù),使用apply函數(shù)進(jìn)行運(yùn)算def top(df, n=2, column='成交量'): return df.sort_values(by=column)[-n:] # 自建函數(shù)df.groupby('城市').apply(top) 直接使用apply函數(shù)進(jìn)行聚合運(yùn)算。
四、cut與qcut的用法qcut是等樣本數(shù),cut是等值區(qū)間分,groupby和cut和qcut結(jié)合使用,可以對(duì)等值或等樣本數(shù)分組后的結(jié)果進(jìn)行分析。 #使用numpy生成兩個(gè)隨機(jī)數(shù)import numpy as npdf = pd.DataFrame({'data1':np.random.randn(1000), 'data2': np.random.randn(1000)})df.head() 將數(shù)據(jù)data1等值區(qū)間四等分。
數(shù)據(jù)data1等樣本數(shù)四等分。 #將數(shù)據(jù)data1等樣本數(shù)四等分quriles_1 = pd.qcut(df.data1,4)quriles_1[:10] 五、apply與applymap的用法apply函數(shù)主要用于對(duì)DataFrame中的某一column或row中的元素執(zhí)行相同的函數(shù)操作,而applymap函數(shù)主要用于對(duì)DataFrame中每一個(gè)元素執(zhí)行系統(tǒng)的操作,apply和applymap都要與lambda結(jié)合使用。
使用apply函數(shù),對(duì)A列的每一個(gè)元素加1。#對(duì)A列的每一個(gè)元素加1df['A'].apply(lambda x:x+1) 使用applymap對(duì)表內(nèi)的每個(gè)元素加1。
定義一個(gè)get函數(shù),對(duì)data2數(shù)據(jù)使用apply函數(shù)做聚合運(yùn)算。 def get(group): return {'min':group.min(),'max':group.max(),'count': group.count(),'mean': group.mean()}df.data2.groupby(quariles).apply(get) 使用unstack函數(shù)顯示數(shù)據(jù)透視表效果。
labels=False采用默認(rèn)的0開始的索引。 # 去掉分組數(shù)值lable,采用默認(rèn)的0開始的索引q = pd.qcut(df.data1, 10, labels=False) df.data2.groupby(q).apply(get).unstack() 六、數(shù)據(jù)透視表數(shù)據(jù)透視表使用的是pivot_table函數(shù),接下來(lái)介紹該函數(shù)使用最多的幾個(gè)參數(shù)。data表示使用數(shù)據(jù)透視表數(shù)據(jù),values表示計(jì)算值,index表示數(shù)據(jù)透視的行,columns表示數(shù)據(jù)透視的列,aggfunc表示計(jì)算類型,margins表示是否顯示合計(jì)列,margins_name表示合計(jì)列的名字。
margins顯示合計(jì),并且margins_name修改合計(jì)名稱。 #margins顯示合計(jì),margins_name修改合計(jì)名稱pd.pivot_table(df,values = '用戶ID',columns ='性別',index='城市',aggfunc='count',margins = True,margins_name ='合計(jì)') 當(dāng)數(shù)據(jù)透視結(jié)果有缺失值時(shí),用fill_value = 0缺失值填充。
aggfunc={'用戶ID':'count','成交量':'sum'},對(duì)用戶ID做計(jì)數(shù)運(yùn)算,對(duì)成交量做求和運(yùn)算。 pd.pivot_table(df,values = ['用戶ID','成交量'],columns='性別',index='城市',aggfunc={'用戶ID':'count','成交量':'sum'},fill_value = 0) reset_index對(duì)數(shù)據(jù)透視結(jié)果重置索引。
|
|