美文网首页
如何在Pandas中使用Apply方法

如何在Pandas中使用Apply方法

作者: Python_Camp | 来源:发表于2022-06-20 14:40 被阅读0次

如何在Pandas中使用Apply方法

apply()方法是数据预处理中最常用的方法之一。
它简化了对pandas系列中的每个元素和pandas DataFrame中的每一行或每一列的函数应用。在本教程中,我们将学习如何在pandas中使用apply()方法--你需要了解Python和lambda函数的基本原理。如果你不熟悉这些,或者需要提高你的Python技能,你可能想试试我们的免费Python基础课程。

让我们直接进入,在 Pandas 系列上应用一个函数
系列是潘达的基础。它们本质上是带有轴标签的一维数组,称为索引。

创建系列对象有不同的方法(例如,我们可以用列表或字典初始化系列)。让我们用两个列表定义一个系列对象,其中包含学生姓名作为索引,学生的身高(厘米)作为数据。


import pandas as pd
import numpy as np
from IPython.display import display

students = pd.Series(data=[180, 175, 168, 190],
                     index=['Vik', 'Mehdi', 'Bella', 'Chriss'])
display(students)
print(type(students))
Vik       180
Mehdi     175
Bella     168
Chriss    190
dtype: int64

上面的代码返回students对象的内容和它的数据类型。

students对象的数据类型是Series,所以我们可以使用apply()方法对其数据应用任何函数。让我们看看如何将学生的身高从厘米转换为英尺。

def cm_to_feet(h):
    return np.round(h/30.48, 2)

print(students.apply(cm_to_feet))
Vik       5.91
Mehdi     5.74
Bella     5.51
Chriss    6.23
dtype: float64

学生的身高被转换为小数点后两位的英尺。为此,我们首先定义了一个进行转换的函数,然后将函数名称不带括号地传递给apply()方法。apply()方法接收系列中的每个元素,并对其应用cm_to_feet()函数。

Pandas DataFrame上应用一个函数
在本节中,我们将学习如何使用apply()方法来操作数据框架中的列和行。

首先,让我们用下面的代码创建一个假的DataFrame,包含一个公司员工的个人信息。

data = pd.DataFrame({'EmployeeName': ['Callen Dunkley', 'Sarah Rayner', 'Jeanette Sloan', 'Kaycee Acosta', 'Henri Conroy', 'Emma Peralta', 'Martin Butt', 'Alex Jensen', 'Kim Howarth', 'Jane Burnett'],
                    'Department': ['Accounting', 'Engineering', 'Engineering', 'HR', 'HR', 'HR', 'Data Science', 'Data Science', 'Accounting', 'Data Science'],
                    'HireDate': [2010, 2018, 2012, 2014, 2014, 2018, 2020, 2018, 2020, 2012],
                    'Sex': ['M', 'F', 'F', 'F', 'M', 'F', 'M', 'M', 'M', 'F'],
                    'Birthdate': ['04/09/1982', '14/04/1981', '06/05/1997', '08/01/1986', '10/10/1988', '12/11/1992', '10/04/1991', '16/07/1995', '08/10/1992', '11/10/1979'],
                    'Weight': [78, 80, 66, 67, 90, 57, 115, 87, 95, 57],
                    'Height': [176, 160, 169, 157, 185, 164, 195, 180, 174, 165],
                    'Kids': [2, 1, 0, 1, 1, 0, 2, 0, 3, 1]
                    })
display(data)


EmployeeName    Department  HireDate    Sex Birthdate   Weight  Height  Kids
0   Callen Dunkley  Accounting  2010    M   04/09/1982  78  176 2
1   Sarah Rayner    Engineering 2018    F   14/04/1981  80  160 1
2   Jeanette Sloan  Engineering 2012    F   06/05/1997  66  169 0
3   Kaycee Acosta   HR  2014    F   08/01/1986  67  157 1
4   Henri Conroy    HR  2014    M   10/10/1988  90  185 1
5   Emma Peralta    HR  2018    F   12/11/1992  57  164 0
6   Martin Butt Data Science    2020    M   10/04/1991  115 195 2
7   Alex Jensen Data Science    2018    M   16/07/1995  87  180 0
8   Kim Howarth Accounting  2020    M   08/10/1992  95  174 3
9   Jane Burnett    Data Science    2012    F   11/10/1979  57  165 1

data = pd.DataFrame({'EmployeeName': ['Callen Dunkley', 'Sarah Rayner', ' Jeanette Sloan', 'Kaycee Acosta', 'Henri Conroy', ' Emma Peralta', 'Martin Butt', 'Alex Jensen', 'Kim Howarth', 'Jane Burnett'],
'部门'。['会计', '工程', '工程', '人力资源', '人力资源', '数据科学', '数据科学', '会计', '数据科学'] 。
'HireDate': [2010, 2018, 2012, 2014, 2014, 2018, 2020, 2018, 2020, 2012],
'性别': ['m', 'f', 'f', 'f', 'm', 'f', 'm', 'm', 'f'] 。
'出生日期': ['04/09/1982', '14/04/1981', '06/05/1997', '08/01/1986', '10/10/1988', '12/11/1992', '10/04/1991', '16/07/1995', '08/10/1992', '11/10/1979'] 。
'重量'。[78, 80, 66, 67, 90, 57, 115, 87, 95, 57],
'身高': [176, 160, 169, 157, 185, 164, 195, 180, 174, 165],
'孩子'。[2, 1, 0, 1, 1, 0, 2, 0, 3, 1]
})
display(data)
雇员姓名 部门 雇用日期 性别 出生日期 体重 身高 孩子
0 Callen Dunkley Accounting 2010 M 04/09/1982 78 176 2
1 Sarah Rayner Engineering 2018 F 14/04/1981 80 160 1
2 Jeanette Sloan Engineering 2012 F 06/05/1997 66 169 0
3 Kaycee Acosta HR 2014 女 08/01/1986 67 157 1
4 Henri Conroy HR 2014 男 10/10/1988 90 185 1
5 Emma Peralta HR 2018 女 12/11/1992 57 164 0
6 Martin Butt 数据科学 2020 男 10/04/1991 115 195 2
7 Alex Jensen 数据科学 2018 男 16/07/1995 87 180 0
8 Kim Howarth 会计 2020 男 08/10/1992 95 174 3
9 Jane Burnett 数据科学 2012 女 11/10/1979 57 165 1

注意

在本节中,我们将研究由公司人力资源部门发起的假请求。我们将通过不同的场景来学习如何使用apply()方法。我们将在每个场景中探索一个新的用例,并使用apply()方法解决它。

场景1
我们假设人力资源部门想发送一封邀请邮件,邮件的开头是对所有员工的友好问候(例如,嘿,Sarah!)

他们要求你创建两列,分别存储员工的名和姓,这样就可以很容易地提到员工的名字。要做到这一点,我们可以使用一个lambda函数,在通过指定的分隔符将字符串分割成一个列表;split()方法的默认分隔符是任何白色空间。让我们看一下代码。

data['FirstName'] = data['EmployeeName'].apply(lambda x : x.split()[0])
data['LastName'] = data['EmployeeName'].apply(lambda x : x.split()[1])
display(data)


EmployeeName    Department  HireDate    Sex Birthdate   Weight  Height  Kids    FirstName   LastName
0   Callen Dunkley  Accounting  2010    M   04/09/1982  78  176 2   Callen  Dunkley
1   Sarah Rayner    Engineering 2018    F   14/04/1981  80  160 1   Sarah   Rayner
2   Jeanette Sloan  Engineering 2012    F   06/05/1997  66  169 0   Jeanette    Sloan
3   Kaycee Acosta   HR  2014    F   08/01/1986  67  157 1   Kaycee  Acosta
4   Henri Conroy    HR  2014    M   10/10/1988  90  185 1   Henri   Conroy
5   Emma Peralta    HR  2018    F   12/11/1992  57  164 0   Emma    Peralta
6   Martin Butt Data Science    2020    M   10/04/1991  115 195 2   Martin  Butt
7   Alex Jensen Data Science    2018    M   16/07/1995  87  180 0   Alex    Jensen
8   Kim Howarth Accounting  2020    M   08/10/1992  95  174 3   Kim Howarth
9   Jane Burnett    Data Science    2012    F   11/10/1979  57  165 1   Jane    Burnett

在上面的代码中,我们在EmployeeName列上应用了lambda函数,从技术上讲,它是一个Series对象。lambda函数将雇员的全名拆分为名和姓。因此,代码又创建了两列,包含了雇员的名和姓。

情景二
现在,我们假设人力资源部门想知道每个员工的年龄和员工的平均年龄,因为他们想确定员工的年龄是否会影响工作满意度和工作投入。

为了完成这项工作,第一步是定义一个函数,获取员工的出生日期并返回其年龄。

def calculate_age(birthdate):
    birthdate = datetime.strptime(birthdate, '%d/%m/%Y').date()
    today = date.today()
    return today.year - birthdate.year - (today.month < birthdate.month)

函数calculate_age()以适当的格式获得一个人的出生日期,在对其进行简单计算后,返回他们的年龄。

下一步是使用apply()方法在DataFrame的Birthdate列上应用该函数,如下所示。

data['Age'] = data['Birthdate'].apply(calculate_age)
display(data)


EmployeeName    Department  HireDate    Sex Birthdate   Weight  Height  Kids    FirstName   LastName    Age
0   Callen Dunkley  Accounting  2010    M   04/09/1982  78  176 2   Callen  Dunkley 39
1   Sarah Rayner    Engineering 2018    F   14/04/1981  80  160 1   Sarah   Rayner  40
2   Jeanette Sloan  Engineering 2012    F   06/05/1997  66  169 0   Jeanette    Sloan   24
3   Kaycee Acosta   HR  2014    F   08/01/1986  67  157 1   Kaycee  Acosta  36
4   Henri Conroy    HR  2014    M   10/10/1988  90  185 1   Henri   Conroy  33
5   Emma Peralta    HR  2018    F   12/11/1992  57  164 0   Emma    Peralta 29
6   Martin Butt Data Science    2020    M   10/04/1991  115 195 2   Martin  Butt    30
7   Alex Jensen Data Science    2018    M   16/07/1995  87  180 0   Alex    Jensen  26
8   Kim Howarth Accounting  2020    M   08/10/1992  95  174 3   Kim Howarth 29
9   Jane Burnett    Data Science    2012    F   11/10/1979  57  165 1   Jane    Burnett 42

雇员姓名 部门 雇用日期 性别 出生日期 体重 身高 孩子 名字 姓氏 年龄

上面的单行语句在Birthdate列的每个元素上应用calculate_age()函数,并将返回的值存储在Age列。

最后一步是计算雇员的平均年龄,如下所示。

print(data['Age'].mean())
32.8

情景3
公司的人力资源经理正在探索为所有员工提供医疗保障的方案。潜在的供应商需要有关雇员的信息。由于DataFrame包含每个员工的体重和身高,让我们假设人力资源经理要求你提供每个员工的身体质量指数(BMI),这样她就可以从潜在的医疗保健供应商那里获得报价。

要完成这个任务,首先,我们需要定义一个计算身体质量指数(BMI)的函数。BMI的公式是体重(公斤)除以身高(米)的平方。因为员工的身高是以厘米为单位的,所以我们需要用身高除以100来得到米的身高。让我们来实现这个函数。

def calc_bmi(weight, height):
    return np.round(weight/(height/100)**2, 2)

下一步是在DataFrame上应用该函数。

data['BMI'] = data.apply(lambda x: calc_bmi(x['Weight'], x['Height']) , axis=1)

这个lambda函数接收每一行的体重和身高值,然后对它们应用calc_bmi()函数来计算其BMI。axis=1参数意味着在DataFrame中迭代行数。

display(data)

EmployeeName    Department  HireDate    Sex Birthdate   Weight  Height  Kids    FirstName   LastName    Age BMI
0   Callen Dunkley  Accounting  2010    M   04/09/1982  78  176 2   Callen  Dunkley 39  25.18
1   Sarah Rayner    Engineering 2018    F   14/04/1981  80  160 1   Sarah   Rayner  40  31.25
2   Jeanette Sloan  Engineering 2012    F   06/05/1997  66  169 0   Jeanette    Sloan   24  23.11
3   Kaycee Acosta   HR  2014    F   08/01/1986  67  157 1   Kaycee  Acosta  36  27.18
4   Henri Conroy    HR  2014    M   10/10/1988  90  185 1   Henri   Conroy  33  26.30
5   Emma Peralta    HR  2018    F   12/11/1992  57  164 0   Emma    Peralta 29  21.19
6   Martin Butt Data Science    2020    M   10/04/1991  115 195 2   Martin  Butt    30  30.24
7   Alex Jensen Data Science    2018    M   16/07/1995  87  180 0   Alex    Jensen  26  26.85
8   Kim Howarth Accounting  2020    M   08/10/1992  95  174 3   Kim Howarth 29  31.38
9   Jane Burnett    Data Science    2012    F   11/10/1979  57  165 1   Jane    Burnett 42  20.94

最后一步是根据BMI的测量结果对员工进行分类。BMI小于18.5为第一组,18.5到24.9之间为第二组,25到29.9之间为第三组,30以上为第四组。为了实现这个解决方案,我们将定义一个函数来返回各种BMI指标,然后在DataFrame的BMI列上应用这个函数来查看每个员工属于哪一类。

def indicator(bmi):
    if (bmi < 18.5):
        return 'Group One'
    elif (18.5 <= bmi < 25):
        return 'Group Two'
    elif (25 <= bmi < 30):
        return 'Group Three'
    else:
        return 'Group Four'

data['BMI_Indicator'] = data['BMI'].apply(indicator)
display(data)

EmployeeName    Department  HireDate    Sex DoB Weight  Height  Kids    FirstName   LastName    Age BMI BMI_Indicator
0   Callen Dunkley  Accounting  2010    M   04/09/1982  78  176 2   Callen  Dunkley 39  25.18   Group Three
1   Sarah Rayner    Engineering 2018    F   14/04/1981  80  160 1   Sarah   Rayner  40  31.25   Group Four
2   Jeanette Sloan  Engineering 2012    F   06/05/1997  66  169 0   Jeanette    Sloan   24  23.11   Group Two
3   Kaycee Acosta   HR  2014    F   08/01/1986  67  157 1   Kaycee  Acosta  36  27.18   Group Three
4   Henri Conroy    HR  2014    M   10/10/1988  90  185 1   Henri   Conroy  33  26.30   Group Three
5   Emma Peralta    HR  2018    F   12/11/1992  57  164 0   Emma    Peralta 29  21.19   Group Two
6   Martin Butt Data Science    2020    M   10/04/1991  115 195 2   Martin  Butt    30  30.24   Group Four
7   Alex Jensen Data Science    2018    M   16/07/1995  87  180 0   Alex    Jensen  26  26.85   Group Three
8   Kim Howarth Accounting  2020    M   08/10/1992  95  174 3   Kim Howarth 29  31.38   Group Four
9   Jane Burnett    Data Science    2012    F   11/10/1979  57  165 1   Jane    Burnett 42  20.94   Group Two

场景4

让我们假设新年即将来临,公司管理层宣布那些有10年以上工作经验的员工将获得额外的奖金。人力资源经理想知道谁有资格获得奖金。

要准备请求的信息,需要在HireDate列上应用下面的lambda函数,如果当前年份和雇佣年份之间的差值大于或等于十年,则返回True,否则返回False。

mask = data['HireDate'].apply(lambda x: date.today().year - x >= 10)
print(mask)
0     True
1    False
2     True
3    False
4    False
5    False
6    False
7    False
8    False
9     True
Name: HireDate, dtype: bool

为了显示合格的员工,我们使用布尔掩码过滤DataFrame行。让我们运行下面的语句并查看结果:
显示(数据(员工画像))

雇员名部门雇佣日期性别年龄体重身高孩子名字姓年龄bmi

EmployeeName    Department  HireDate    Sex DoB Weight  Height  Kids    FirstName   LastName    Age BMI
0   Callen Dunkley  Accounting  2010    M   04/09/1982  78  176 2   Callen  Dunkley 39  25.18
2   Jeanette Sloan  Engineering 2012    F   06/05/1997  66  169 0   Jeanette    Sloan   24  23.11
9   Jane Burnett    Data Science    2012    F   11/10/1979  57  165 1   Jane    Burnett 42  20.94

0 callen dunkley会计2010 m 04/09/1982 78 176 2 callen dunkley 39 25.18
2珍妮特斯隆工程2012 f 06/05/1997 66 169 0珍妮特斯隆24 23.11
9简·伯内特数据科学2012 f 11/10/1979 57 165 1简·伯内特42 20.94

场景5

假设明天是母亲节,公司为所有有孩子的女性员工准备了一份母亲节礼物。人力资源团队让你准备一份有资格获得这份礼物的员工名单。要完成这项任务,我们需要编写一个简单的lambda函数,该函数考虑Sex和Kids列以提供所需的结果,如下所示:

data[data.apply(lambda x: True if x ['Gender'] == 'F' and x['Kids'] > 0 else False, axis=1)]


EmployeeName    Department  HireDate    Sex Birthdate   Weight  Height  Kids    FirstName   LastName    Age BMI
1   Sarah Rayner    Engineering 2018    F   14/04/1981  80  160 1   Sarah   Rayner  40  31.25
3   Kaycee Acosta   HR  2014    F   08/01/1986  67  157 1   Kaycee  Acosta  36  27.18
9   Jane Burnett    Data Science    2012    F   11/10/1979  57  165 1   Jane    Burnett 42  20.94

运行上面的代码将返回将收到礼物的员工列表。

如果女性员工至少有一个孩子,lambda函数返回True;否则,返回False。在DataFrame上应用lambda函数的结果是一个布尔掩码,我们直接使用它来过滤DataFrame的行。

结论

在本教程中,我们通过不同的示例了解了apply()方法的作用以及如何使用它。apply()方法是对pandas中的Series或DataFrame的每个值应用函数的一种强大而有效的方法。由于apply()方法使用了Python的C扩展,所以当遍历pandas DataFrame的所有行时,它执行得更快。但是,这不是一般的规则,因为通过列执行相同的操作会比较慢。

相关文章

网友评论

      本文标题:如何在Pandas中使用Apply方法

      本文链接:https://www.haomeiwen.com/subject/ddcevrtx.html