强大的匿名函数lambda使用方法,结合map、apply等

2022-11-14 16:08:48 浏览数 (1)

lambda有自身用法,更多的是结合内置函数的用法。 本文转载自CSDN,为weixin_668的原创文章,点击阅读原文即可跳转。

目录

一、lambda自身的基本用法 1、语法 2、特性 3、例子 二、lambda结合内置函数(map,filter)等用法 (1) python内置的map() (2)python内置的filter() 三、numpy中的lambda用法 (1)map()方法 (2)numpy.apply_along_axis方法 四、pandas中的lambda用法 (1)结合map (2)结合apply (3)结合applymap()

一、lambda自身的基本用法

1、语法

在Python中,lambda的语法形式如下: lambda argument_list: expression lambda是Python预留的关键字,argument_listexpression由用户自定义。

(1)argument_list是参数列表,它的结构与Python中函数(function)的参数列表是一样的。比如:
代码语言:javascript复制
x
a, b
a=1, b=2
*args      # 输入是任意个数的参数,(隐性要求输入参数必须能进行算术运算)
**kwargs   # 输入是任意键值对参数
a, b=1, *args
......
(2)expression是一个关于参数的表达式。表达式中出现的参数需要在argument_list中有定义,并且表达式只能是单行的。比如:
代码语言:javascript复制
1
None
a   b
sum(a)  : sum()要求()里的变量可迭代,这是sum函数本身所决定的,如可以为数值列表
1 if x== else 0
......

2、特性

(1)lambda函数是匿名的:所谓匿名函数,就是没有名字的函数。

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

(3)lambda函数一般功能简单:单行expression决定了lambda函数不可能完成复杂的逻辑,只能完成非常简单的功能。

3、例子

(1)简单使用

代码语言:javascript复制
in:lambda x : 5
out:<function __main__.<lambda>(x)>
# 可以发现这是一个函数,怎么单独使用呢?我想,可以将此赋值给一个对象,万物皆对象
 
# 进一步演示
y = lambda x : 5 
y(4)
out:5
# 此处只出输出了结果,但并未给任何变量
 
y = lambda x : x 5 
y(4)
out:9
 
# 将变量赋值,只是演示它本身的方法和过程,这么简单操作在现实中并不这么用
y = lambda a,b : a*b 
c = y(5,6)
c
out:30

(2)结合内置函数使用。 例如sum,当然,sum也可换成任何函数,包括自定义的函数,但注意要满足函数本身的参数的要求

代码语言:javascript复制
y = lambda x : sum(x)
a = [1,2,3,4,5]
c = y(a)
c
out:15

(3)使用*args

代码语言:javascript复制
y = lambda *args: sum(args)
y(3,2,1)
out:6
# 注意此处与上一个用法的区别

(4)结合if else使用。 注意if 和else 可能要成对出现,试过很多次,只有if 没有else一直报错。

代码语言:javascript复制
y = lambda x : 1  if x > 5  else 0
y(6)
out:1
y(2)
out:0

二、lambda结合内置函数

主要是根据内置函数的要求放置lambad函数的位置,数据要满足函数要求。

1、python内置的map()

如map()函数的格式是: map(function,iterable,...) 第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列,返回的是一个集合。

那么lambda就要放在map函数的function处,map后面参数就要放可迭代的对象。

代码语言:javascript复制
a = ['1','2', 3, 4]
b = list(map(lambda x : float(x)  if type(x) == str else None, a)) # 本函数意思是,若对象是字符串,转换为数值型
b
out:[1.0, 2.0, 3, 4]

2、python内置的filter()

函数能够从可迭代对象(如字典、列表)中筛选某些元素,并生成一个新的迭代器。可迭代对象是一个可以被“遍历”的Python对象,也就是说,它将按顺序返回各元素,这样我们就可以在for循环中使用它。

filter()函数格式是:

filter(function, iterable) 返回一个可迭代的filter对象,可以使用list()函数将其转化为列表,这个列表包含过滤器对象中返回的所有的项。

代码语言:javascript复制
a = [1, 2, 3, 6, 7]
y = filter(lambda x : x % 2 == 0, a)
list(y)    # 需要用list取出值
out:[2, 6]
 
names = ['Sum', 'And', 'One', 'Two', 'Fore']
list(filter(lambda x: x[0] in 'SaT', names))    # x[0]相当于对列表中的每个元素的字符串切片
out:['Sum', 'Two']

三、numpy中的lambda用法

需要结合map()方法或np.apply_along_axis()方法,它只能对一行或一列操作,不能对整个多维数组操作,相当只能于对一维数组操作。

(1)map()方法

代码语言:javascript复制
import numpy as np
arr = np.arange(15).reshape(3,5)
arr
out:
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
 
arr[0]
out: array([0, 1, 2, 3, 4])
 
# 将数组中的arr[0]这一行中的元素,进行操作,能被2整除返回
y = list(map(lambda x : 'BB' if x % 2 == 0 else 'AA' , arr[0]))
y
out:['BB', 'AA', 'BB', 'AA', 'BB']
 
# 比较一下,x[0],对列操作了
y = list(map(0lambda x : 'BB' if x[0] %2==0 else 'AA' , arr))
y
out: ['AA', 'BB', 'AA']

(2)numpy.apply_along_axis方法 格式:

numpy.apply_along_axis(function, axis, arr, *args, **kwargs)

作用: 将arr数组的每一个元素经过func函数变换形成的一个新数组。

参数介绍: 其中function,axis,arr是必选的。 function: 是一个函数; axis:表示函数function对arr是作用于行还是列; arr:为进行操作的数组; 可选参数:*args, **kwargs。都是function函数额外的参数。

遗留问题:numpy暂未找到对所有元素操作的方法,但可以在自定义函数中用索引方法定义对多维数组在每一行上进行多列的操作。

代码语言:javascript复制

# 借用以上数据arr
# 示例1:
def f(x):
    if x[0] % 2 == 0 :
        return  'A'
    else :
        return  'B'
 
y = np.apply_along_axis(f, 0, arr)
y
out:array(['A', 'B', 'A', 'B', 'A'], dtype='<U1')
# 改用lambda
y = np.apply_along_axis(lambda x : 'A' if x[0] % 2 == 0  else 'B', 0, arr)
y
out:array(['A', 'B', 'A', 'B', 'A'], dtype='<U1')
 
# 示例2:
def f(x):
     return (x[0] x[1])
np.apply_along_axis(f, 1, arr)
out: array([ 1, 11, 21])
 
# 改用lambda
y= np.apply_along_axis(lambda x: x[0]   x[1], 1, arr)
y
out: array([ 1, 11, 21])

四、pandas中的lambda用法

与numpy类似,可以与**map()、apply()、applymap()**等方法结合使用。

三者的具体用法参见官网。

(1)map: 格式:

Series.map(*arg*, *na_action=None*)

map只能用于Series。

map是element-wise的,对Series中的每个数据调用一次函数; map主要是作用将函数作用于一个Series的每一个元素。

代码语言:javascript复制
import numpy as np
import pandas as pd
arr = np.arange(15).reshape(3,5)
a = pd.DataFrame(arr,columns=['A','B','C','D','E'])
a
out:
          A  B  C  D  E
        0 0  1  2  3  4
        1 5  6  7  8  9
        2 10 11 12 13 14
 
a['A'].map(lambda x :  "A" if x % 2 ==0 else "B")
out:
        0    A
        1    B
        2    A
        Name: A, dtype: object
 
a['A'].apply(lambda x :  "A" if x % 2 ==0 else "B")
out:
        0    A
        1    B
        2    A
        Name: A, dtype: object

(2)apply: 格式: Series.apply(*func*, *convert_dtype=True*, *args=()*, ***kwargs*)

DataFrame.apply(*func*, *axis=0*, *raw=False*, *result_type=None*, *args=()*, ***kwargs*)

不仅可以用于Series,还可以用于DataFrame;

用于Series时,如果 func 返回一个 Series 对象,则结果将是一个 DataFrame。

用于DataFrame时,根据轴参数是列或者行,返回沿 DataFrame 的给定轴应用的结果。

map、apply在用于Series时,对每一个值进行处理,结果一致,两者区别可能是输入参数的要求的区别。

一般情况下,在pandas中apply应用更灵活,更广泛,尤其是自定义函数带多个参数时,建议使用apply。

代码语言:javascript复制
a.apply(lambda x :  x.max(), axis=0)
out:
        A    10
        B    11
        C    12
        D    13
        E    14
        dtype: int64
 
a.apply(lambda x :  x.max(), axis=1)
out:
        0     4
        1     9
        2    14
        dtype: int64
 
a.apply(lambda x : x['A']   x['B'],axis=1)
out:
        0     1
        1    11
        2    21
        dtype: int32
 
a.apply(lambda x : 'A'  x.astype(str))
out:
            A   B    C    D    E
        0  A0   A1   A2   A3   A4
        1  A5   A6   A7   A8   A9
        2  A10  A11  A12  A13  A14

(3)applymap() 格式: DataFrame.applymap(*func*, *na_action=None*, ***kwargs*)

对DataFrame的每一个数据进行操作的时候用 applymap()方法,返回结果是DataFrame格式。

代码语言:javascript复制
a.applymap(np.square)
out:
          A   B   C   D   E
        0 0   1   4   9   16
        1 25  36  49  64  81
        2 100 121 144 169 196
 
# 能被2整除的返回AA,否则返回BB
a.applymap(lambda x : "AA" if x % 2 == 0 else "BB")
out:
          A  B  C  D  E
        0 AA BB AA BB AA
        1 BB AA BB AA BB
        2 AA BB AA BB AA
 
# 将每个元素转换成字符串,并取出长度
a.applymap(lambda x: len(str(x)))
out:
          A B C D E
        0 1 1 1 1 1
        1 1 1 1 1 1
        2 2 2 2 2 2
 
# applymap因是对每个元素操作,不能使用astype更改数据类型,但可用python方法。
# 下述方法与a.apply(lambda x : 'A'  x.astype(str))结果一致
a.applymap(lambda x : 'A'  str(x))
out:
          A   B   C   D   E
        0 A0  A1  A2  A3  A4
        1 A5  A6  A7  A8  A9
        2 A10 A11 A12 A13 A14

0 人点赞