二.Pandas 数据结构之 DataFrame使用教程
三.Pandas进阶:DataFrame的简单运算、统计与排序
四.Pandas进阶:使用Join、Merge、Concat、Append 合并DataFrame
五.Pandas进阶:apply的优雅使用方法
沿
DataFrame
的轴应用函数
Pnadas 的官方文档中是这样介绍
apply
方法的。通俗点讲就是
apply
函数需传入一个方法,同时需指定这个方法的参数是按哪个轴进行传递的,传入
axis=0
代表按索引轴传递参数(即竖向传递,把每列的值传入函数中进行计算);传入
axis=1
代表按 列名轴传递参数(即横向传递,把每行的值传入函数中进行计算);所以我们可以知道无论是按索引轴或是按列名(columns)轴传递的对象类型都是Series
Example
:
df = pd.DataFrame({
'name': ['lihua', 'lilei', 'hanmeimei', 'xiaoming', 'xiaohong'],
'math': [99, 100, 80, 50, 118],
'english': [94, 83, 99, 79, 108],
'chinese': [107, 82, 76, 100, 113]
name math english chinese
0 lihua 99 94 107
1 lilei 100 83 82
2 hanmeimei 80 99 76
3 xiaoming 50 79 100
4 xiaohong 118 108 113
对一列或某几列数据进行操作
当你想知道各科第一名的成绩时:
s = df[['math', 'english', 'chinese']].apply(max)
math 118
english 108
chinese 113
dtype: int64
当你想知道各科成绩的平均分时:
s = df[['math', 'english', 'chinese']].apply(np.average)
math 89.4
english 92.6
chinese 95.6
dtype: float64
当你想知道每个学生的总分时:
df.index = df['name']
s = df[['math', 'english', 'chinese']].apply(sum, axis=1)
lihua 300
lilei 265
hanmeimei 255
xiaoming 229
xiaohong 339
dtype: int64
分组后对每组数据进行特定的操作
当我们的DF数据结构是这样的时候:
name math english chinese class
0 lihua 99 94 107 class_1
1 lilei 100 83 82 class_2
2 hanmeimei 80 99 76 class_2
3 xiaoming 50 79 100 class_1
4 xiaohong 118 108 113 class_2
按班级分组并求每个班级的各科的平均分
s = df.groupby('class')[['math', 'english', 'chinese']].apply(lambda x: x.apply(np.average))
math english chinese
class
class_1 74.500000 86.500000 103.500000
class_2 99.333333 96.666667 90.333333
求分组后每组总分排第二的学生
def get_second(x: pd.DataFrame):
x = x.sort_values('sum', ascending=False)
if len(x) < 2:
return x.iloc[0]
return x.iloc[1]
df['sum'] = df[['math', 'english', 'chinese']].apply(sum, axis=1)
result = df.groupby('class').apply(get_second)
name math english chinese class sum
class
class_1 xiaoming 50 79 100 class_1 229
class_2 lilei 100 83 82 class_2 265
该例传入了自定义的函数 get_second
。其原理为apply方法对分组后形成的两个(按class分组,示例中只有class_1, class_2两个班级的学生)DF对象分别应用get_second
函数。get_second
函数内部对传入的DF按sum列从大到小进行了排序,同时要取排名第二位的就要校验传入的数据列是否大于2.
下图中按步骤介绍了该例是如何一步一步实现的:
使用apply函数的关键是具体的操作思路一定要清晰,根据我们想要的结果推到出是否要分组后再进行应用函数,或者直接可以在原有的DF对象中应用,在原有的DF对象中应用函数也应该先想好是对每行应用还是对每列应用。关键的第一步走好之后,那就是实现应用函数的具体功能了,这就要根据我们实际的需求来实现了。