Pandas的apply函数是可以自动根据function遍历每一个数据,然后返回一个数据结构为Series的结果,Pandas 的很多对象都可以使用 apply()
来调用函数,如 Dataframe、Series、分组对象、各种时间序列等。
一般语法:
df.apply(func, axis=0, args=(), **kwds)
参数:
func:应用于每列或每行的函数,不管是自定义的函数,还是匿名函数lambda
axis:应用函数的轴方向,{0 or ‘index’, 1 or ‘columns’},默认是0
0 or ‘index’: 按行
1 or ‘columns’: 按列
args: func 的位置参数
**kwds:要作为关键字参数传递给 func 的其他关键字参数
返回结果:
Series 或者 DataFrame:沿数据的给定轴应用 func 的结果
函数定义
函数 fun 参数,只需要传入这个函数的函数名就可以了,第一个参数接收一个 Series,还可以定义位置参数和关键字参数,如以下定义一个函数:
def mymax(x):
return x.max()
df.apply(mymax) # 应用函数
如果,给定位置参数和关键字参数的话:
def myfun(x, a, max=None):
return x + a - max
df.apply(myfun, 10, max=1) # 应用函数
总结一下,fun 可传入的函数形式有以下几种(DataFrame 和 Series 均适用):
ser.apply(fun) # 自定义
ser.apply(max) # python 内置函数
ser.apply(lambda x: x*2) # lambda
ser.apply(np.mean) # numpy 等其他库的函数 ufunc
ser.apply(pd.Series.first_valid_index) # Pandas 自己的函数
ser.apply('count') # Pandas 自己的函数
ser.apply('shape') # Pandas 自己的属性
ser.apply('tan') # numpy 的 ufunc 名
# 多个函数
ser.apply([sum, 'count']) # 相当于 .agg
ser.apply(np.array(["sum", "mean"]))
ser.apply({'Q1':sum, 'Q2':'count'}) # 同上
此外,apply 还可以传入多个函数,对数据进行聚合,实现 agg 的效果:
# 读取一份文件
df=pd.read_csv(r'C:/Users/Administrator/Desktop/team.csv',encoding='gbk')
# 结果如下:
姓名 团队 Q1 Q2 Q3 Q4
0 刘一 E 89 21 24 64
1 陈二 C 36 37 37 57
2 张三 A 57 60 18 84
3 李四 C 93 96 71 78
4 王五 D 65 49 61 86
5 赵六 C 24 13 87 43
6 孙七 B 61 95 94 8
7 周八 A 9 10 99 37
8 吴九 D 64 93 57 72
9 郑十 A 77 9 26 67
df=df.apply(['min','max'])
# 结果如下:
姓名 团队 Q1 Q2 Q3 Q4
min 刘一 A 9 9 18 8
max 陈二 E 93 96 99 86
df=df.apply({
'Q1':'max',
'Q2':'min'
})
# 结果如下:
Q1 93
Q2 9
dtype: int64
df=df.apply({
'Q1':'mean',
'Q2':['min','max']
})
# 结果如下:
Q1 Q2
mean 57.5 NaN
min NaN 9.0
max NaN 96.0
apply应用在Pandas中,其核心功能其实可以概括为一句话:
apply:我本身不处理数据,我们只是数据的搬运工。
apply自身是不带有任何数据处理功能的,但可以用作是对其他数据处理方法的调度器,至于调度什么又为谁而调度呢?这是理解apply的两个核心环节:
调度什么?调度的是apply函数接收的参数,即apply接收一个数据处理函数为主要参数,并将其应用到相应的数据上。所以调度什么取决于接收了什么样的数据处理函数;
为谁调度?也就是apply接收的数据处理函数,其作用对象是谁?或者说数据处理的粒度是什么?答案是数据处理的粒度包括了点线面三个层面:即可以是单个元素(标量,scalar),也可以是一行或一列(series),还可以是一个dataframe。