《利用Python進行資料分析》——Chapter9:資料聚合和分組
阿新 • • 發佈:2018-12-20
對資料集進行分組並對各組應用一個函式,這是資料分析的一個重要環節,將資料集準備好後,接下來的任務就是計算分組統計或深成透視表
GroupBy技術(分組)
建立一個GroupBy物件,再呼叫GroupBy的各種方法計算相關資料
df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'], 'key2' : ['one', 'two', 'one', 'two', 'one'], 'data1' : np.random.randn(5), 'data2' : np.random.randn(5)}) grouped = df['data1'].groupby(df['key1']) #先訪問data1,再根據key1呼叫groupby (df.groupby(xxx)) #建立一個GroupBy物件 grouped.mean() grouped.size()
# groupby的引數是分組的鍵,分組鍵可以是Series,也可以是任何長度適當的陣列,也可以是DataFrame的列名 df.groupby(df['key1']) #以Series為分組鍵 states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio']) years = np.array([2005, 2005, 2006, 2005, 2006]) df['data1'].groupby([states, years]).mean() #以任何長度的陣列為分組鍵 df.groupby('key1') #以DataFrame的列名為分組鍵
- 對分組(GroupBy物件)進行迭代
GroupBy支援迭代,返回的一組二元元組:分組名+資料塊 >>>for name, group in df.groupby('key1'): print(name) print(group) a key1 key2 data1 data2 0 a one -1.676303 -0.424336 1 a two 0.043207 -0.172227 4 a one -0.165924 -0.145246 b key1 key2 data1 data2 2 b one 1.449175 0.155494 3 b two -0.379370 -0.075793 對資料片段做任何操作:將這些資料片段做成一個字典 pieces = dict(list(df.groupby('key1'))) #list既將剛剛列印的東西作為一個列表,dict是將列印的name作為key,將group作為value
- 選取一個或一組列
> 對於由DataFrame產生的GroupBy物件,如果用一個或一組列名對其進行索引,就能實現選取部分列進行聚合的目的
df.groupby(['key1', 'key2'])[['data2','data1']].mean()
#以一個數組作為索引,返回的是DataFrame
df.groupby(['key1', 'key2'])['data2'].mean()
#以單個列名作為索引,返回的是Series
- 通過Series或字典進行GroupBy
> 通過字典或Series給列名分組,然後再根據新分的組GroupBy
mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
'd': 'blue', 'e': 'red', 'f' : 'orange'}
by_column = people.groupby(mapping, axis=1)
by_column.sum()
map_series = pd.Series(mapping)
map_series
people.groupby(map_series, axis=1).count() #以Series作為分組鍵
- 通過函式進行分組
函式作為分組鍵的傳入,則該函式會在各個***索引值***上被呼叫一次,其返回值都會被用作分組名稱
people.groupby(len).sum() #按人名長度進行分組,直接傳入函式名稱,不用帶(),也不用帶引數
# 將函式和陣列、列表、字典、Series混合使用也不是問題
key_list = ['one', 'one', 'one', 'two', 'two']
people.groupby([len, key_list]).sum()
- 根據索引級別分組
用level關鍵字傳入級別編號,用axis=1對豎向GroupBy
hier_df.groupby(level='cty', axis=1).count()
資料聚合
# 直接使用groupby內含的方法
>>> grouped['data1'].quantile(0.9)
>>> grouped.describe()
# 使用自己的聚合函式,將函式名稱傳入aggregate或agg方法即可:
>>> def peak_to_peak(arr):
return arr.max() - arr.min()
>>> grouped.agg(peak_to_peak)
# 經過優化的GroupBy的方法
count #分組中非NA值的數量
sum #非NA值的和
mean #非NA值的平均數
median #非NA值的算術中位數
std\var #無偏(分母n-1)標準差和方差
min\max #非NA值的最小值和最大值
prod #非NA值的積
first\last #第一個和最後一個非NA值
- 面向列的多函式應用 對不同的列使用不同的聚合函式,或一次應用多個函式
# 傳入一組函式或函式名,得到的DataFrame的列就會以相應的函式命名
>>> grouped_pct.agg(['mean', 'std', peak_to_peak])
>>> grouped_pct.agg([('foo', 'mean'), ('bar', np.std)])
#由(name, function)元組組成的列表作為引數傳入,各元組的第一個元素會被用作DataFrame的列名
# 應用多個函式,將函式以列表形式傳入
>>> functions = ['count', 'mean', 'max']
>>> result = grouped['tip_pct', 'total_bill'].agg(functions)
# 對不同的列應用不同的函式,向agg傳入一個從列名對映到函式的字典
>>> grouped.agg({'tip_pct' : ['min', 'max', 'mean', 'std'], 'size' : 'sum'})
- 以“無索引”的形式返回聚合函式:分組鍵不作為索引
grouped = tips.groupby(['day', 'smoker'], as_index=False) #day和smoker不作為返回的dataframe的索引
分組級運算和轉換
聚合知識分組運算的一種而已,它接受能夠將一維陣列簡化為標量值的函式。 將介紹transform和apply方法,能夠執行更多其他的分組運算