DataFrame 可以使用apply 函数对行或者列的数据进行修改,在apply里传入一个函数,apply的作用是让每一行或者每一列的数据都应用传入的函数进行处理。此外,还有pipe和applymap函数,他们功能类似但应用范围不同,下面是他们的应用范围:
具体使用哪一种,取决于所操作的对象是 DataFrame,还是 Series ;是行、列,还是元素。
我用最简单的一个例子来讲解pipe函数的链式编程
import pandas as pd
data = [
{'语文': 90, '数学': 92},
{'语文': 98, '数学': 87},
{'语文': 87, '数学': 90},
{'语文': 90, '数学': 98},
]
def add_sum_column(df):
# 添加总分列
result = df.copy()
columns = result.columns.tolist()
if '平均值' in columns:
columns.remove('平均值')
result['总分'] = result[columns].sum(axis=1)
return result
def add_mean_column(df):
# 添加平均值列
result = df.copy()
columns = result.columns.tolist()
if '总分' in columns:
columns.remove('总分')
result['平均值'] = result[columns].mean(axis=1)
return result
df = pd.DataFrame(data, index=['小明', '小红', '小刚', '小丽'])
df_sum = add_sum_column(df)
df_mean = add_mean_column(df_sum)
print(df_mean)
程序输出结果
数学 语文 总分 平均值
小明 92 90 182 91.0
小红 87 98 185 92.5
小刚 90 87 177 88.5
小丽 98 90 188 94.0
最初的DataFrame并没有总分和平均值这两列,我在示例中定义了两个函数,分别增加总分列和平均值列,之后分两次调用函数。所谓链式编程,简单讲就是把多次函数调用连接在一起,方便代码编写和阅读,使用pipe进行链式编程,示例代码如下
df = pd.DataFrame(data, index=['小明', '小红', '小刚', '小丽'])
result = df.pipe(add_sum_column).pipe(add_mean_column)
print(result)
pipe函数传入的应用函数,可以是自定义函数,也可以是第三方函数,这个函数必须返回处理后的DataFrame, 多个函数要使用多个pipe函数进行调用。
对每一行或者每一列数据应用apply函数进行计算,比如计算各学科的平均值,计算学生各个科目的平均值
import pandas as pd
import numpy as np
data = [
{'语文': 90, '数学': 92},
{'语文': 98, '数学': 87},
{'语文': 87, '数学': 90},
{'语文': 90, '数学': 98},
]
df = pd.DataFrame(data, index=['小明', '小红', '小刚', '小丽'])
print(df.apply(np.mean)) # 逐行进行操作, 求语文和数学的平均值
print(df.apply(np.mean, axis=1)) # 逐列进行操作, 求每个学生的各科平均值
程序输出结果
数学 91.75
语文 91.25
dtype: float64
应用apply进行操作时,其结果容易让我们产生误解,比如axis=1时,我代码注释里写的是逐行进行操作,那么结果难道不应该是求每一列的平均值么,怎么变成了求每一行数据的平均值?关于这个问题,我教大家一个好的方法来理解。当axis=0时,是逐行操作,因此最终计算出一行新的数据,那么就只能是计算各个学科的平均值, axis=1时,逐列进行操作,最终计算出一个新的列,那么这个新的列只能是以学生做维度,计算他们各个科目的平均值,这样理解是不是就容易一些了呢
applymap是元素级应用函数,它会对每一个元素产生作用
import pandas as pd
data = [
{'语文': '90', '数学': '92'},
{'语文': '98', '数学': '87'},
{'语文': '87', '数学': '90'},
{'语文': '90', '数学': '98'},
]
df = pd.DataFrame(data, index=['小明', '小红', '小刚', '小丽'])
print(df['语文'])
程序输出结果是
小明 90
小红 98
小刚 87
小丽 90
Name: 语文, dtype: object
dtype是object, 而不是我们期望的int64,我们可以使用applymap将所有数据都转成int类型
df = pd.DataFrame(data, index=['小明', '小红', '小刚', '小丽'])
df = df.applymap(lambda x: int(x))
print(df['语文'])
程序输出结果
小明 90
小红 98
小刚 87
小丽 90
Name: 语文, dtype: int64
QQ交流群: 211426309