1. 程式人生 > >《利用Python進行資料分析》——Chapter9:資料聚合和分組

《利用Python進行資料分析》——Chapter9:資料聚合和分組

對資料集進行分組並對各組應用一個函式,這是資料分析的一個重要環節,將資料集準備好後,接下來的任務就是計算分組統計或深成透視表

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的列名為分組鍵
  1. 對分組(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
  1. 選取一個或一組列
> 對於由DataFrame產生的GroupBy物件,如果用一個或一組列名對其進行索引,就能實現選取部分列進行聚合的目的
df.groupby(['key1', 'key2'])[['data2','data1']].mean()
			#以一個數組作為索引,返回的是DataFrame
df.groupby(['key1', 'key2'])['data2'].mean()
			#以單個列名作為索引,返回的是Series
  1. 通過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作為分組鍵
  1. 通過函式進行分組

函式作為分組鍵的傳入,則該函式會在各個***索引值***上被呼叫一次,其返回值都會被用作分組名稱

people.groupby(len).sum()		#按人名長度進行分組,直接傳入函式名稱,不用帶(),也不用帶引數
# 將函式和陣列、列表、字典、Series混合使用也不是問題
key_list = ['one', 'one', 'one', 'two', 'two']
people.groupby([len, key_list]).sum()
  1. 根據索引級別分組
用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值
  1. 面向列的多函式應用 對不同的列使用不同的聚合函式,或一次應用多個函式
# 傳入一組函式或函式名,得到的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'})
  1. 以“無索引”的形式返回聚合函式:分組鍵不作為索引
grouped = tips.groupby(['day', 'smoker'], as_index=False)		#day和smoker不作為返回的dataframe的索引

分組級運算和轉換

聚合知識分組運算的一種而已,它接受能夠將一維陣列簡化為標量值的函式。 將介紹transform和apply方法,能夠執行更多其他的分組運算