Python数据聚合和分组运算(1)-GroupBy Mechanics
前言
Python的pandas包提供的數(shù)據(jù)聚合與分組運(yùn)算功能很強(qiáng)大,也很靈活。《Python for Data Analysis》這本書第9章詳細(xì)的介紹了這方面的用法,但是有些細(xì)節(jié)不常用就容易忘記,遂打算把書中這部分內(nèi)容總結(jié)在博客里,以便復(fù)習(xí)查看。根據(jù)書中的章節(jié),這部分知識(shí)包括以下四部分:
1.GroupBy Mechanics(groupby技術(shù))
2.Data Aggregation(數(shù)據(jù)聚合)
3.Group-wise Operation and Transformation(分組級(jí)運(yùn)算和轉(zhuǎn)換)
4.Pivot Tables and Cross-Tabulation(透視表和交叉表)
本文是第一部分,介紹groupby技術(shù)。
?
一、分組原理
核心:
1.不論分組鍵是數(shù)組、列表、字典、Series、函數(shù),只要其與待分組變量的軸長度一致都可以傳入groupby進(jìn)行分組。
2.默認(rèn)axis=0按行分組,可指定axis=1對列分組。
?
對數(shù)據(jù)進(jìn)行分組操作的過程可以概括為:split-apply-combine三步:
1.按照鍵值(key)或者分組變量將數(shù)據(jù)分組。
2.對于每組應(yīng)用我們的函數(shù),這一步非常靈活,可以是python自帶函數(shù),可以是我們自己編寫的函數(shù)。
3.將函數(shù)計(jì)算后的結(jié)果聚合。
圖1:分組聚合原理(圖片來自《Python for Data Analysis》page 252)
import pandas as pd import numpy as npdf = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],'key2' : ['one', 'two', 'one', 'two', 'one'],'data1' : np.random.randn(5),'data2' : np.random.randn(5)})我們將key1當(dāng)做我們的分組鍵值,對data1進(jìn)行分組,再求每組的均值:
grouped = df['data1'].groupby(df['key1'])語法很簡單,但是這里需要注意grouped的數(shù)據(jù)類型,它不在是一個(gè)數(shù)據(jù)框,而是一個(gè)GroupBy對象。
grouped實(shí)際上,在這一步,我們并沒有進(jìn)行任何計(jì)算僅僅是創(chuàng)建用key1分組后創(chuàng)建了一個(gè)GroupBy對象,我們后面函數(shù)的任何操作都是基于這個(gè)對象的。
求均值:
grouped.mean()剛剛我們只是用了key1進(jìn)行了分組,我們也可以使用兩個(gè)分組變量,并且通過unstack方法進(jìn)行結(jié)果重塑:
means = df['data1'].groupby([df['key1'], df['key2']]).mean() means means.unstack以上我們的分組變量都是df內(nèi)部的Series,實(shí)際上只要是和key1等長的數(shù)組也可以:
states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio']) years = np.array([2005, 2005, 2006, 2005, 2006]) df['data1'].groupby([states, years]).mean()二、對分組進(jìn)行迭代
GroupBy對象支持迭代操作,會(huì)產(chǎn)生一個(gè)由分組變量名和數(shù)據(jù)塊組成的二元元組:
for name, group in df.groupby('key1'):print nameprint group如果分組變量有兩個(gè):
for (k1,k2), group in df.groupby(['key1','key2']):print k1,k2print group我們可以將上面的結(jié)果轉(zhuǎn)化為list或者dict,來看看結(jié)果是什么樣的:
list(df.groupby(['key1','key2']))看不太清楚,我們來看看這個(gè)列表的第一個(gè)元素:
list(df.groupby(['key1','key2']))[0]同樣,我們也可以將結(jié)果轉(zhuǎn)化為dict(字典):
dict(list(df.groupby(['key1','key2']))) dict(list(df.groupby(['key1','key2'])))[('a','one')]以上都是基于行進(jìn)行分組,因?yàn)槟J(rèn)情況下groupby是在axis=0方向(行方向)進(jìn)行分組,我們可以指定axis=1方向(列方向)進(jìn)行分組:
grouped=df.groupby(df.dtypes,axis=1) list(grouped)[0] dict(list(grouped))注意,
'''下面兩段語句功能一樣''' df.groupby('key1')['data1'] df.data1.groupby(df.key1)三、通過字典進(jìn)行分組
people = pd.DataFrame(np.random.randn(5, 5),columns=['a', 'b', 'c', 'd', 'e'],index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis']) people.ix[2:3, ['b', 'c']] = np.nan # 添加缺失值 people假如,我們想按列進(jìn)行聚合,該怎么操作呢?
我們根據(jù)實(shí)際情況,對列名建立字典,然后將此字典傳入groupby,切記指定axis=1,因?yàn)槲覀兪菍α羞M(jìn)行分組聚合:
mapping = {'a': 'red', 'b': 'red', 'c': 'blue','d': 'blue', 'e': 'red', 'f' : 'orange'} by_columns=people.groupby(mapping,axis=1) by_columns.mean()既然我們可以通過傳入字典來對列進(jìn)行分組,那么肯定也可以通過傳入Series來對列進(jìn)行分組了(Series中的index就相當(dāng)字典中的key嘛):
map_series = pd.Series(mapping) people.groupby(map_series,axis=1).count()四、通過函數(shù)進(jìn)行分組
剛剛我們分組時(shí)利用了dict和series建立映射,對于一些復(fù)雜的需求,我們可以直接對groupby函數(shù)傳遞函數(shù)名來進(jìn)行分組,以剛才的people數(shù)據(jù)為例,如果我們想按行分組,分組的key是每個(gè)人名的字母長度,該怎么做呢?比較直接的想法是相對每個(gè)名字求長度,建立一個(gè)數(shù)組,然后將這個(gè)數(shù)組傳入groupby,我們來試驗(yàn)一下:
l=[len(x) for x in people.index] people.groupby(l).count()方案可行,那么有沒有更快捷更優(yōu)美的方法呢?當(dāng)然有啦,我們只需將len這個(gè)函數(shù)名傳給groupby即可:
people.groupby(len).count()除了傳遞函數(shù),我們也可以將函數(shù)和dict,series,array一起使用,畢竟最后都會(huì)統(tǒng)統(tǒng)轉(zhuǎn)化為數(shù)組:
key_list = ['one', 'one', 'one', 'two', 'two'] people.groupby([len, key_list]).min()五、根據(jù)索引級(jí)別分組
剛剛我們的數(shù)據(jù)索引只有一級(jí),當(dāng)數(shù)據(jù)有多級(jí)索引時(shí),可以通過level指定我們想要分組的索引,注意要使用axis=1表示按列:
columns = pd.MultiIndex.from_arrays([['Asian', 'Asian', 'Asian', 'America', 'America'],['China','Japan','Singapore','United States','Canada']], names=['continent', 'country']) hier_df = pd.DataFrame(np.random.randn(4, 5), columns=columns) hier_df我們按洲進(jìn)行分組求和:
轉(zhuǎn)載于:https://www.cnblogs.com/zhangzhangwhu/p/7219651.html
總結(jié)
以上是生活随笔為你收集整理的Python数据聚合和分组运算(1)-GroupBy Mechanics的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 『深度应用』人脸识别最新进展及发展方向
- 下一篇: 需求分析挑战之旅(疯狂的订餐系统)(6)