pandas——groupby、agg,對錶格資料分組與統計
阿新 • • 發佈:2019-01-13
文章目錄
- DataFrame
- 分組,並對分組進行迭代
- 1. 按key1(一個列)分組,其實是按key1的值
- 2. 按[key1, key2](多個列)分組
- 3. 按函式分組
- 4. 按字典分組
- 5. 按索引級別分組
- 6.將函式跟陣列、列表、字典、Series混合使用也不是問題,因為任何東西最終都會被轉換為陣列
- 將這些資料片段做成字典
- 分組後進行一些統計、計算等
- 橫方向上
- agg的應用
groupby功能:分組
groupby + agg(聚集函式們): 分組後,對各組應用一些函式,如’sum’,‘mean’,‘max’,‘min’…
groupby預設縱方向上分組,axis=0
DataFrame
import pandas as pd
import numpy as np
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)})
print(df)
data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two
4 -0.297191 0.954447 a one
分組,並對分組進行迭代
list(df.groupby(['key1']))#list後得到:[(group1),(group2),......]
[('a', data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one), ('b', data1 data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two)]
list後得到:[(group1),(group2),…]
每個資料片(group)格式: (name,group)元組
1. 按key1(一個列)分組,其實是按key1的值
groupby物件支援迭代,產生一組二元元組:(分組名,資料塊),(分組名,資料塊)…
for name,group in df.groupby(['key1']):
print(name)
print(group)
a
data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one
b
data1 data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two
2. 按[key1, key2](多個列)分組
對於多重鍵,產生的一組二元元組:((k1,k2),資料塊),((k1,k2),資料塊)…
第一個元素是由鍵值組成的元組
for name,group in df.groupby(['key1','key2']):
print(name) #name=(k1,k2)
print(group)
('a', 'one')
data1 data2 key1 key2
0 -0.410122 0.247895 a one
4 -0.297191 0.954447 a one
('a', 'two')
data1 data2 key1 key2
1 -0.62747 -0.989268 a two
('b', 'one')
data1 data2 key1 key2
2 0.179488 -0.05457 b one
('b', 'two')
data1 data2 key1 key2
3 -0.299878 -1.640494 b two
3. 按函式分組
4. 按字典分組
5. 按索引級別分組
6.將函式跟陣列、列表、字典、Series混合使用也不是問題,因為任何東西最終都會被轉換為陣列
將這些資料片段做成字典
dict(list(df.groupby(['key1'])))#dict(list())
{'a': data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one, 'b': data1 data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two}
分組後進行一些統計、計算等
1. 分組後,返回一個含有分組大小的Series
按key1分組
df.groupby(['key1']).size()
key1
a 3
b 2
dtype: int64
dict(['a1','x2','e3'])
{'a': '1', 'e': '3', 'x': '2'}
按[key1,key2]分組
df.groupby(['key1','key2']).size()
key1 key2
a one 2
two 1
b one 1
two 1
dtype: int64
2. 對data1按key1進行分組,並計算data1列的平均值
df['data1'].groupby(df['key1']).mean()
#groupby沒有進行任何的計算。它只是進行了一個分組
key1
a -0.444928
b -0.060195
Name: data1, dtype: float64
df.groupby(['key1'])['data1'].mean()#理解:對df按key1分組,並計算分組後df['data1']的均值
#等價於:df.groupby(['key1']).data1.mean()
key1
a -0.444928
b -0.060195
Name: data1, dtype: float64
說明:
groupby沒有進行任何的計算。它只是進行了一個分組。
資料(Series)根據分組鍵進行了聚合,產生了一個新的Series,其索引為key1列中的唯一值。
這種索引操作所返回的物件是一個已分組的DataFrame(如果傳入的是列表或陣列)或已分組的Series
df.groupby(['key1'])['data1'].size()
key1
a 3
b 2
Name: data1, dtype: int64
3.對data1按[key1,key2]進行分組,並計算data1的平均值
df['data1'].groupby([df['key1'],df['key2']]).mean()
key1 key2
a one -0.353657
two -0.627470
b one 0.179488
two -0.299878
Name: data1, dtype: float64
df.groupby(['key1','key2'])['data1'].mean()
#等價於:df.groupby(['key1','key2']).data1'.mean()
key1 key2
a one -0.353657
two -0.627470
b one 0.179488
two -0.299878
Name: data1, dtype: float64
通過兩個鍵對資料進行了分組,得到的Series具有一個層次化索引(由唯一的鍵對組成):
df.groupby(['key1','key2'])['data1'].mean().unstack()
key2 | one | two |
---|---|---|
key1 | ||
a | -0.353657 | -0.627470 |
b | 0.179488 | -0.299878 |
在上面這些示例中,分組鍵均為Series。實際上,分組鍵可以是任何長度適當的陣列。非常靈活。
橫方向上
按列的資料型別(df.dtypes)來分
df共兩種資料型別:float64和object,所以會分為兩組(dtype(‘float64’),資料片),(dtype(‘O’), 資料片)
list(df.groupby(df.dtypes, axis=1))
[(dtype('float64'), data1 data2
0 -0.410122 0.247895
1 -0.627470 -0.989268
2 0.179488 -0.054570
3 -0.299878 -1.640494
4 -0.297191 0.954447), (dtype('O'), key1 key2
0 a one
1 a two
2 b one
3 b two
4 a one)]
agg的應用
groupby+agg 可以對groupby的結果同時應用多個函式
SeriesGroupBy的方法agg()引數:
aggregate(self, func_or_funcs, * args, ** kwargs)
func: function, string, dictionary, or list of string/functions
返回:aggregated的Series
s= pd.Series([10,20,30,40])
s
0 10
1 20
2 30
3 40
dtype: int64
for n,g in s.groupby([1,1,2,2]):
print(n)
print(g)
1
0 10
1 20
dtype: int64
2
2 30
3 40
dtype: int64
s.groupby([1,1,2,2]).min()
1 10
2 30
dtype: int64
#等價於這個:
s.groupby([1,1,2,2]).agg('min')
1 10
2 30
dtype: int64
s.groupby([1,1,2,2]).agg(['min','max'])#加[],func僅接受一個引數
min | max | |
---|---|---|
1 | 10 | 20 |
2 | 30 | 40 |
常常這樣用:
df
data1 | data2 | key1 | key2 | |
---|---|---|---|---|
0 | -0.410122 | 0.247895 | a | one |
1 | -0.627470 | -0.989268 | a | two |
2 | 0.179488 | -0.054570 | b | one |
3 | -0.299878 | -1.640494 | b | two |
4 | -0.297191 | 0.954447 | a | one |
比較下面,可以看出agg的用處:
df.groupby(['key1'])['data1'].min()
key1
a -0.627470
b -0.299878
Name: data1, dtype: float64
df.groupby(['key1'])['data1'].agg({'min'})
min | |
---|---|
key1 | |
a | -0.627470 |
b | -0.299878 |
#推薦用這個√
df.groupby(['key1']).agg({'data1':'min'})#對data1列,取各組的最小值,名字還是data1
data1 | |
---|---|
key1 | |
a | -0.627470 |
b | -0.299878 |
#按key1分組後,aggregate各組data1的最小值和最大值:
df.groupby(['key1'])['data1'].agg({'min','max'})
max | min | |
---|---|---|
key1 | ||
a | -0.297191 | -0.627470 |
b | 0.179488 | -0.299878 |
#推薦用這個√
df.groupby(['key1']).agg({'data1':['min','max']})
data1 | ||
---|---|---|
min | max | |
key1 | ||
a | -0.627470 | -0.297191 |
b | -0.299878 | 0.179488 |
可以對groupby的結果更正列名(不推薦用這個,哪怕在後面單獨更改列名)
# 對data1,把min更名為a,max更名為b
df.groupby(['key1'])['data1'].agg({'a':'min','b':'max'})#這裡的'min' 'max'為兩個函式名
d:\python27\lib\site-packages\ipykernel_launcher.py:2: FutureWarning: using a dict on a Series for aggregation
is deprecated and will be removed in a future version
a | b | |
---|---|---|
key1 | ||
a | -0.627470 | -0.297191 |
b | -0.299878 | 0.179488 |