【数据清洗系利】lambda表达式配合使用的四种函数

【数据清洗】lambda表达式配合使用的四种函数

标签:数据清洗、python

一、什么是lambda表达式

​ lambda 表达式是一个匿名函数,lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象,是一个匿名函数,即没有函数名的函数。

​ lambda表达式常用来声明匿名函数,即没有函数名字的临时使用的小函数,常用在临时需要一个类似于函数的功能但又不想定义函数的场合。它只可以包含一个表达式,不允许包含其他复杂的语句,但在表达式中可以调用其他函数,该表达式的计算结果相当于函数的返回结果。

​ lambda表达式可以接受任意数量的参数,但函数只能包含一个表达式。表达式是lambda函数执行的一段代码,它可以返回任何值,返回函数对象。

lambda表达式可以返回函数对象。

在Python中,lambda的语法是唯一的。其形式如下:

lambda argument_list: expression

​ 我们可以有很多个参数,但是只能有一个表达式。lambda操作符不能有任何声明,它返回一个函数对象。其中,lambda是Python预留的关键字,argument_list和expression由用户自定义。

基本特性

lambda函数有如下特性:

  1. lambda函数是匿名的:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数返回的函数对象是没有名字的,需要在lambda表达式外赋予名字。

  2. lambda函数有输入和输出:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值。

  3. lambda函数一般功能简单:单行expression决定了lambda函数不可能完成太过复杂的逻辑,只能完成较为简单的功能。由于其实现的功能一目了然,甚至不需要专门的名字来说明。

下面是一些lambda表达式的基本用法示例:

lambda x,y: x*y                # 函数输入是x和y,输出是它们的积x*y
lambda x,y=2: x*y              # lambda表达式也支持设定参数默认值
lambda: "CDA data analysis"    # 函数没有输入参数,输出是设定的字符串
lambda *args: sum(args)        # 输入是任意个数的参数,输出是它们的和(输入参数必须能够进行加法运算)
lambda **kwargs: 1             # 输入是任意键值对参数,输出是1
使用方法

​ lambda表达式返回的是一个函数对象,其本质上只有一种用法,那就是定义一个lambda匿名函数。在实际中,根据这个lambda函数应用场景的不同,lambda函数的用法有很多种,其中一种就是将lambda函数作为参数传递给其他函数。

​ Python有少数内置函数可以接收lambda函数作为参数,进行组合使用,这也是最为常见的一种用法。典型的此类内置函数有一下这四种。filter函数:筛选列表中所有满足条件的元素,lambda函数作为过滤列表元素的条件。

  • filter函数:筛选列表中所有满足条件的元素,lambda函数作为过滤列表元素的条件。

  • map函数:根据提供的函数对指定序列做映射,lambda函数作为映射。

  • sorted函数:对列表中所有元素进行排序,lambda函数可以用于指定排序规则。

  • reduce函数:列表中两两相邻元素逐一进行运算,lambda函数用于指定运算条件。

list_x = [1,2,3,4,5]
filter(lambda x: x % 3 == 0, list_x)
sorted(list_x, key=lambda x:(10-x))
map(lambda x:x+1, list_x)
reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数

filter函数

​ filter( )函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,注意返回的不是列表,如果要转换为列表,可以使用 list()来转换。

​ 该函数接收两个参数,第一个为函数,第二个为序列,filter函数的重点在于过滤,所以它必须有一个用于判断的工具,这就是function参数的函数,传入的函数返回值必须是布尔类型,序列的每个元素作为参数逐个传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

# 语法
filter(function, iterable)

# 参数
function:判断函数
iterable:可迭代对象,例如列表、元组、字符串等

# 返回
返回一个迭代器对象

简单示例一:

# 找出1-10之间的偶数
list(filter(lambda x: x%2 == 0,range(1,11))) 

# output
[2, 4, 6, 8, 10]

简单示例二:

# 删除空字符
list(filter(lambda x:x.strip(), ['cda', '', '\t', 'cc', '  ','\n']))

# output
['cda', 'cc']

简单示例三:

# 求水仙花数
list(filter(lambda x:x == (x//100)**3 + (x//10%10)**3 + (x%10)**3,range(100,1000)))

# output
[153, 370, 371, 407]

map函数

​ map( )会根据提供的函数对指定序列做映射,即根据传入的函数逐一对序列中的元素进行计算。

​ 该函数至少接收两个参数,第一个参数为函数function,第二个参数为可迭代对象iterable,第二个参数序列中的每一个元素调用第一个参数 function函数来进行计算,返回包含每次 function 函数返回值的可迭代对象,map( )函数和filter( )函数一样,在python3版本中返回的都是可迭代对象,有需要的话用list( )函数将其转换成列表格式。

# 语法
map(function, iterable, ...)

# 参数
function:判断函数
iterable:一个或多个序列、可迭代对象,例如列表、元组、字符串等

# 返回
返回一个迭代器对象

简单示例一:

list(map(lambda x:x ** 2, [1,2,3,4,5]))   # 计算列表各个元素的平方

# output
[1, 4, 9, 16, 25]

简单示例二:

# 将文本转换为小写
str_list = ["Alan","CDA","ccongg"]
list(map(lambda x:x.lower(),str_list))

# output
['alan', 'cda', 'ccongg']

​ map( )函数可以仅对一个序列进行运算,也可以输入多个序列进行并行运算,对多个序列同一位置的元素来逐步进行运算。序列不要求长度必须相同,最后返回的结果遵循木桶准则,以多个序列中长度最短的长度为准,即传入一个长度为4的序列,一个长度为7的序列,最终返回的序列长度为4。

简单示例三:

# 提供了两个列表,对相同位置的列表数据进行运算
# 计算向量的模
import math
x_list = [-2,-4,4,2]
y_list = [1,3,-3,-1]
list(map(lambda x, y: math.sqrt(x**2 + y**2),x_list,y_list))

# output
[2.23606797749979, 5.0, 5.0, 2.23606797749979]

sorted函数

​ sorted( ) 函数的作用是对所有可迭代的对象进行排序操作。它和sort函数的作用类似,但它们之间还是有一些区别:

  • sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。

  • list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内置函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

sort( )和sorted( )函数的区别:

a = [5,7,6,3,4,1,2]     # 定义列表
b = (5,7,6,3,4,1,2)     # 定义元组
a.sort()         # sort用以列表的排序,无法用于元组之类的可迭代对象
a

sorted(b)
b
b.sort()

执行结果:

out1: [1, 2, 3, 4, 5, 6, 7]        # sort()对a列表排序后,a本身发生改变 
out2: [1, 2, 3, 4, 5, 6, 7]        # sorted()对b元组进行排序,返回的是列表格式
out3: (5,7,6,3,4,1,2)              # 可以看出,b本身没有发生变化
out4: 
AttributeError: 'tuple' object has no attribute 'sort'         # 元组无法使用sort()函数

语法:

sorted(iterable, key=None, reverse=False)

参数说明:

  • iterable:可迭代对象。
  • key:主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。具体使用中通常以lambda匿名函数作为key参数的传入,用以指定用以排序的对象。
  • reverse:排序规则,reverse为逆序的意思,当reverse = True表示降序 , reverse = False表示升序。默认为升序。

返回:

重新排序后的列表,无论用什么可迭代对象进行排序,最终返回的都是列表。

简单示例一:

​ 一维的序列无需key参数,只需要可迭代对象和reverse排序规则即可,注意,第一个参数可以默认为iterable可迭代对象,不可更改顺序,后两个可选参数传入函数时,必须包含变量名称,例如

a = [5,7,6,3,4,1,2]
sorted(a,reverse=True)         # 降序,正常执行

sorted(reverse=True,city_rank)     # SyntaxError: 序列必须在第一个位置
sorted(a,True)                     # TypeError: 没有变量名的定义,必须为reverse=True

# output 1:
[7, 6, 5, 4, 3, 2, 1]
# output 2:
SyntaxError: positional argument follows keyword argument
# output 3:
TypeError: sorted expected 1 arguments, got 2

简单示例二:

​ 二维及以上的序列可以使用key参数传入lambda匿名函数结合使用,实现按条件排序的作用,lambda函数的左右主要是用来指定用以排序的目标。

city_rank=[('北京',1),('广州',3),('深圳',4),('上海',2)]
sorted(city_rank,key = lambda x:x[1])                     # 利用key
sorted(city_rank,key = lambda x:x[1], reverse=True)       # 降序

执行结果:

[('北京', 1), ('上海', 2), ('广州', 3), ('深圳', 4)]

[('深圳', 4), ('广州', 3), ('上海', 2), ('北京', 1)]

reduce函数

​ reduce() 函数在 python 2 是内置函数, 从python 3 开始移到了 functools 模块。所以在使用前需要先导入,否则无法直接使用。

​ reduce函数的功能是,从左到右对一个序列的项逐个地应用一个有两个参数的函数,用函数的功能对序列的项逐个的进行运算,最终返回所使用的函数的结果。例如:

from functools import reduce        # 导入reduce函数
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])       #  计算的就是((((1+2)+3)+4)+5),返回结果15

reduce有三个参数,分别是

function有两个参数的函数, 必需参数
sequencetuple ,list ,dictionary, string等可迭代对象,必需参数
initial初始值, 可选参数,默认为0
  • function,即有两个符合序列数据类型运算参数的函数,可以是lambda匿名函数。

  • sequence,即序列,可以是python中的列表、元组、字符串、字典格式以及其他可迭代对象的序列。

  • initial,即初始值,是可选参数,没有该参数时,函数运行以序列中的第一个元素开始进行计算,如果有该参数,则以该参数为初始值开始和序列中的第一个元素开始计算。

​ reduce的工作过程是 :在迭代sequence(tuple ,list ,dictionary, string等可迭代对象)的过程中,首先把前两个元素传给函数参数,函数加工后,然后把得到的结果和第三个元素作为两个参数传给函数参数, 函数加工后得到的结果又和第四个元素作为两个参数传给函数参数,依次类推。如果传入了initial值,那么首先传的就不是 sequence的第一个和第二个元素,而是initial值和第一个元素。经过这样的累计计算之后合并序列到一个单一返回值。

将前面的例子中的加号改为乘号,实际上就从求和的函数变为求阶乘的函数:

from functools import reduce        # 导入reduce函数
reduce(lambda x, y: x*y, [1, 2, 3, 4, 5])       #  计算的就是((((1*2)*3)*4)*5),返回结果120

​ 我们再玩一些稍微复杂一些的用法,只是简单基本的用法介绍,对新手来说,理解肯定是不够的,所以下面讲点更深入的例子,以元组、字典类型的数据序列为目标来进行操作,我们的目标是计算元组中每一个元素中对应的薪资(wage)的平均数:

from functools import reduce        # 导入reduce函数
cda = ({'name':'cda01','wage':10500,"education":"BA"},
       {'name':'cda14','wage':15000,"education":"master"},
       {'name':'cda67','wage':12000,"education":"BA"},
       {'name':'cda96','wage':8000,"education":"BA"},
       {'name':'cda127','wage':11000,"education":"BA"},
       {'name':'cda141','wage':18000,"education":"master"})
red = lambda x,y: x + y["wage"]     # 建立lambda函数,用以计算数据中wage的总和,注意x,y的不同之处
total_wage = reduce(red,cda,0)                 # 使用reduce函数,设置初始值为0,
avg_wage = total_wage/len(cda)                 # 计算平均值
print(avg_wage)

# output
12416.666666666666

也能用t实它现分组:

from functools import reduce
cda = ({'name':'cda01','wage':10500,"education":"BA"},
       {'name':'cda14','wage':15000,"education":"master"},
       {'name':'cda67','wage':12000,"education":"BA"},
       {'name':'cda96','wage':8000,"education":"BA"},
       {'name':'cda127','wage':11000,"education":"BA"},
       {'name':'cda141','wage':18000,"education":"master"})
def group_by_edu(accumulator,value):
    accumulator[value['education']].append(value['name'])
    return accumulator
grouped = reduce(group_by_edu, cda, {'master':[], 'BA':[]})   # 初始值是实现目标的最重要的点
print(grouped)

# output
{'master': ['cda14', 'cda141'], 'BA': ['cda01', 'cda67', 'cda96', 'cda127']}

​ 通过以上两个案例可以看出,简单加减示例中很少出现的初始值参数initial恰恰是实现复杂目标的最重要的点,它可以说是整个实现过程中的地基,是塑造最终结果的骨骼。

​ 更复杂的操作就没必要使用reduce+lambdal了,可以使用一些其他的函数或者自定义来进行处理。

总结

​ 以上四种就是能和lambda函数结合一起使用的函数,除了reduce函数在python3中移到了 functools 模块。需要先导入模块才能使用,其他三种都是python的内置函数,可以直接使用。它们之中有一些相同点和不同点,通过总结后更方便区分和以后的使用。

相同点:

1、都是用以处理可迭代对象;

2、都可以配合lambda匿名函数进行使用;

不同点:

1、功能不同,lambda函数的作用不同

filter函数:筛选列表中所有满足条件的元素,lambda函数作为过滤列表元素的条件。关键词:筛选

map函数:根据提供的函数对指定序列做映射,lambda函数作为映射。关键词:映射

sorted函数:对列表中所有元素进行排序,lambda函数可以用于指定排序规则。关键词:排序

reduce函数:列表中两两相邻元素逐一进行运算,lambda函数用于指定运算条件。关键词:元素间运算

2、reduce函数不是内置函数

3、参数个数不同、序列和函数的传入顺序要求不同

​ 记住不同函数的功能,最好的方法就是函数名,filter的意思为过滤器、过滤;map有提供信息(尤指其编排或组织方式)的意思,sorted则是排序,整理的意思,reduce为减少,缩小的意思。如此一看,就能很深刻的记住这几种函数的作用和用法了。

lambda函数作为过滤列表元素的条件。关键词:筛选

map函数:根据提供的函数对指定序列做映射,lambda函数作为映射。关键词:映射

sorted函数:对列表中所有元素进行排序,lambda函数可以用于指定排序规则。关键词:排序

reduce函数:列表中两两相邻元素逐一进行运算,lambda函数用于指定运算条件。关键词:元素间运算

2、reduce函数不是内置函数

3、参数个数不同、序列和函数的传入顺序要求不同

​ 记住不同函数的功能,最好的方法就是函数名,filter的意思为过滤器、过滤;map有提供信息(尤指其编排或组织方式)的意思,sorted则是排序,整理的意思,reduce为减少,缩小的意思。如此一看,就能很深刻的记住这几种函数的作用和用法了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值