数据应用
当某些作用于分组的操作,既不适合使用agg()方法进行聚合时,也不适合使用transform()方法进行转换时,便可以让apply()方法派上用场了。apply()方法的使用是十分灵活的,它可以在许多标准用例中替代聚合和转换,另外还可以处理一些比较特殊的用例。
apply()方法的语法格式如下:
apply(func, axis=0, broadcast=None, raw=False, reduce=None,result_type=None,
args=(), **kwds)
上述方法中常用参数表示的含义如下:
(1) func:表示应用于某一行或某一列的函数。
(2) axis:表示函数操作的轴向,“0”或“index”表示将函数应用于列上,“1”或“columns”表示将函数应用于行上,默认为0。
(3) broadcast:表示是否将数据进行广播。若设为False或None,则会返回一个Series对象,其长度跟索引的长度或列数一样;若设为True,则表示结果将被广播到原始对象中,原始的索引和列将会被保留。
假设现在有一个10行4列的表格,从左边数表格中的数据都是数值类型的,最后一列的数据是字符串类型的,如图1所示。
data1 | data2 | data3 | key | |
---|---|---|---|---|
0 | 80 | 41 | 30 | b |
1 | 23 | 87 | 78 | a |
2 | 25 | 58 | 23 | a |
3 | 63 | 68 | 66 | b |
4 | 94 | 72 | 16 | b |
5 | 92 | 89 | 59 | a |
6 | 99 | 60 | 20 | b |
7 | 92 | 42 | 23 | a |
8 | 82 | 53 | 24 | a |
9 | 99 | 65 | 40 | a |
图1 表格示例
在图1的表格中,按照key一列的数据进行分组,将表格拆分成a、b两组,将max()方法作用于每个分组中,求出每个分组中的最大值。
首先,创建一个与图51中表格结构相同的DataFrame对象,代码如下:
In [29]: from pandas import DataFrame, Series
import pandas as pd
import numpy as np
data_frame = DataFrame({'data1': [80,23,25,63,94,92,99,92,82,99],
'data2': [41,87,58,68,72,89,60,42,53,65],
'data3': [30,78,23,66,16,59,20,23,24,40],
'key': list('baabbabaaa')})
data_frame
Out[29]:
data1 data2 data3 key
0 80 41 30 b
1 23 87 78 a
2 25 58 23 a
3 63 68 66 b
4 94 72 16 b
5 92 89 59 a
6 99 60 20 b
7 92 42 23 a
8 82 53 24 a
9 99 65 40 a
创建好DataFrame对象后,调用groupby()方法按key列进行分组,并打印出每个分组中的数据,示例代码如下。
In [30]: # 对数据进行分组
data_by_group = data_frame.groupby('key')
# 打印分组数据
dict([x for x in data_by_group])['a']
Out[30]:
data1 data2 data3 key
1 23 87 78 a
2 25 58 23 a
5 92 89 59 a
7 92 42 23 a
8 82 53 24 a
9 99 65 40 a
In [31]: dict([x for x in data_by_group])['b']
Out[31]:
data1 data2 data3 key
0 80 41 30 b
3 63 68 66 b
4 94 72 16 b
6 99 60 20 b
上述示例中,以“key”列为分组键将data_frame对象进行分组,为了能够将每个分组的数据显示出来,可以使用列表推导式将分组对象构建成列表。这里,可以把包含所有分组的列表转换为字典,其中分组键作为字典的键,分组中的数据作为字典中的值。通过输出结果可以清楚地看到,分组a和分组b中的具体数据。
接着,我们自定义一个对每个元素加10的plus_ten()函数,然后调用apply()方法,将plus_ten()函数应用到每一个元素中,具体如下。
In [32]: # 对每个元素加10
def plus_ten(data_frame):
return data_frame.iloc[:, :3] + 10
data_by_group.apply(plus_ten)
Out[32]:
data1 data2 data3
0 90 51 40
1 33 97 88
2 35 68 33
3 73 78 76
4 104 82 26
5 102 99 69
6 109 70 30
7 102 52 33
8 92 63 34
9 109 75 50
从输出结果中可以看出,每个元素较之前的元素都加上10 ,这说明使用apply()方法同样能实现聚合的效果。