分组与聚合的过程分为下面这三步
拆分:将数据集按照一些标准拆分为若干个组
应用:将某个函数或者方法应用到每个分组
合并:将产生的新值整合到结果对象中
通过groupby()方法将数据拆分成组
group by(by=None, level=None, as_index=True, sort=True)
参数含义如下:
by:用于确定进行分组的依据
axis:表示分组轴的方向,可以为0或1,默认为0
level:如果某个轴是一个MultiIndex对象(索引层次结构),则会按照特定级别或多个级别分组
as_index:表示聚合后的数据是否以组标签作为索引的DataFrame对象输出,接收布尔值,默认为True
sort:表示是否对分组标签进行排序,接收布尔值,默认为True
在进行分组时,可以通过groupby()方法的by参数来指定按什么标准分组,by参数可以接收的数据有多种形式,类型也不必相同,常用的分组方式主要有以下四种:
-
列表或数组,比长度必须与待分组的轴一样
-
DataFrame对象中某列的名称
-
字典或Series对象,给待分组轴上的值与分组名称之间的对应关系
-
函数,用于处理轴索引或索引中的各个标签
通过列名进行分组
df = pd.DataFrame({"key":['C','B','C','A','B','B','A','C','A'],
"Data":[2,4,6,8,10,1,14,16,18]})
print(df)
# 把列名key传给by参数,表示将key作为分组键
df.groupby(by="key")
# 得到的对象结果是一个可以迭代的对象,只有在整整需要时才会执行计算,可以用for循环进行遍历出来
--------------------------------下面是输出结果------------------------------------
key Data
0 C 2
1 B 4
2 C 6
3 A 8
4 B 10
5 B 1
6 A 14
7 C 16
8 A 18
---------------------------------------------------------------------------
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001D87F7C2C50>
# 上述得到一个DataFrameGroupBy对象,该对象可迭代,可以用for循环进行循环遍历
group_obj = df.groupby('key')
for i in group_obj:
# 输出三个元组,每个元组的第一个元素作为该组的名称
print(i)
-----------------------------------下面是是输出结果-----------------------------------
('A', key Data
3 A 8
6 A 14
8 A 18)
('B', key Data
1 B 4
4 B 10
5 B 1)
('C', key Data
0 C 2
2 C 6
7 C 16)
通过Series对象进行分组
df = pd.DataFrame({'key1':['A','A','B','B','A'],
'key2':['one','two','one','two','one'],
'data1':[2,3,4,6,8],
'data2':[3,5,6,3,7]})
print(df)
# 再创建一个Series对象
se = pd.Series(['a','b','c','a','b'])
se
-------------------------------------下面是输出结果-----------------------------------
key1 key2 data1 data2
0 A one 2 3
1 A two 3 5
2 B one 4 6
3 B two 6 3
4 A one 8 7
----------------------------------------
0 a
1 b
2 c
3 a
4 b
dtype: object
# 将se对象传递给by参数,作为分组键
group_obj = df.groupby(se)
for i in group_obj:
# 根据Series对象的位置索引来进行分组,index相同,那么就为同一组,例如a为(0,3),那么df中,index为0,3的就为同一组
print(i)
-----------------------------------下面是输出结果----------------------------------
('a', key1 key2 data1 data2
0 A one 2 3
3 B two 6 3)
('b', key1 key2 data1 data2
1 A two 3 5
4 A one 8 7)
('c', key1 key2 data1 data2
2 B one 4 6)
# 当Series长度与原数据的索引值长度不一样时
se = pd.Series(['a','a','b'])
print(se)
group_obj = df.groupby(se)
for i in group_obj:
print(i)
------------------------------------------下面是输出结果------------------------------------------
0 a
1 a
2 b
dtype: object
--------------------------------------
('a', key1 key2 data1 data2
0 A one 2 3
1 A two 3 5)
('b', key1 key2 data1 data2
2 B one 4 6)
通过字典进行分组
from pandas import DataFrame,Series
num_df = DataFrame({'a':[1,2,3,4,5],
'b':[6,7,8,9,10],
'c':[11,12,13,14,15],
'd':[5,4,3,2,1],
'e':[10,9,8,7,6]})
print(num_df)
# 常见一个表示分组规则的字典,其中字典的键为num_df对象的列名称,值为自定义的分组名称
mapping = {'a':'第一组','b':'第二组','c':'第一组','d':'第三组','e':'第二组'}
mapping
---------------------------------------------下面是输出结果---------------------------------------------
a b c d e
0 1 6 11 5 10
1 2 7 12 4 9
2 3 8 13 3 8
3 4 9 14 2 7
4 5 10 15 1 6
--------------------------------------------------------------------------
{'a': '第一组', 'b': '第二组', 'c': '第一组', 'd': '第三组', 'e': '第二组'}
# 分组代码如下
by_num = num_df.groupby(mapping,axis=1) # 这里如果按0轴分分不了,就不会有输出结果,0轴指index在这里
for i in by_num:
print(i)
----------------------------------------下面是输出结果------------------------------------------
('第一组', a c
0 1 11
1 2 12
2 3 13
3 4 14
4 5 15)
('第三组', d
0 5
1 4
2 3
3 2
4 1)
('第二组', b e
0 6 10
1 7 9
2 8 8
3 9 7
4 10 6)
通过函数进行分组
df = pd.DataFrame({'a':[1,2,3,4,5],
'b':[6,7,8,9,10],
'c':[5,4,3,2,1]},
index=['sun','Jack','Alice','Helen','Job'])
df
-------------------------下面书输出结果-----------------------------
a b c
sun 1 6 5
Jack 2 7 4
Alice 3 8 3
Helen 4 9 2
Job 5 10 1
# 使用内置函数len进行分组,len是长度函数(即根据字符串长度进行分组)
group_by = df.groupby(len)
for i in group_by:
print(i)
--------------------------------下面是输出结果--------------------------------
(3, a b c
sun 1 6 5
Job 5 10 1)
(4, a b c
Jack 2 7 4)
(5, a b c
Alice 3 8 3
Helen 4 9 2)