「數據清洗」lambda表達式配合使用的四種函數

2020-12-16 CDA數據分析師

標籤:數據清洗、python

lambda表達式配合使用的四種函數一、什麼是lambda表達式基本特性使用方法filter函數map函數sorted函數reduce函數總結

什麼是lambda表達式

lambda 表達式是一個匿名函數,lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象,是一個匿名函數,即沒有函數名的函數。

lambda表達式常用來聲明匿名函數,即沒有函數名字的臨時使用的小函數,常用在臨時需要一個類似於函數的功能但又不想定義函數的場合。它只可以包含一個表達式,不允許包含其他複雜的語句,但在表達式中可以調用其他函數,該表達式的計算結果相當於函數的返回結果。

lambda表達式可以接受任意數量的參數,但函數只能包含一個表達式。表達式是lambda函數執行的一段代碼,它可以返回任何值,返回函數對象。

lambda表達式可以返回函數對象。

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

lambda argument_list: expression

我們可以有很多個參數,但是只能有一個表達式。lambda操作符不能有任何聲明,它返回一個函數對象。其中,lambda是Python預留的關鍵字,argument_list和expression由用戶自定義。

基本特性

lambda函數有如下特性:

lambda函數是匿名的:所謂匿名函數,通俗地說就是沒有名字的函數。lambda函數返回的函數對象是沒有名字的,需要在lambda表達式外賦予名字。lambda函數有輸入和輸出:輸入是傳入到參數列表argument_list的值,輸出是根據表達式expression計算得到的值。lambda函數一般功能簡單:單行expression決定了lambda函數不可能完成太過複雜的邏輯,只能完成較為簡單的功能。由於其實現的功能一目了然,甚至不需要專門的名字來說明。下面是一些lambda表達式的基本用法示例:

lambda x,y: x*y # 函數輸入是x和y,輸出是它們的積x*ylambda 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 mathx_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用以列表的排序,無法用於元組之類的可迭代對象asorted(b)bb.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]) # 利用keysorted(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)# output12416.666666666666

也能用t實它現分組:

from functools import reducecda = ({'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 accumulatorgrouped = 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為減少,縮小的意思。如此一看,就能很深刻的記住這幾種函數的作用和用法了。

相關焦點

  • Java8中lambda表達式的語法,別人都會的,你還不會嗎?「一」
    lambda表達式JSR-335首次定義了在Java中使用lambda表達式的基本規範,當前的實現就是針對JSR-335規範的。 lambda表達式是一種緊湊的、傳遞行為的方式。Lambda表達式本質上是為了解決方便的將代碼作為數據傳遞的難題。
  • Python匿名函數:Lambda表達式
    【1】何為Lambda表達式?我們以一張圖形進入主題:從圖中我們可以看出lambda表達式幾點特徵:簡潔性,符合了Python的一貫宗旨;起到了函數的作用,但未顯示函數名稱,這就是匿名函數;有形參;有返回值的。
  • Lambda 表達式的 10 個示例
    作為開發人員,我發現學習和掌握lambda表達式的最佳方法就是勇於嘗試,儘可能多練習流API和lambda表達式,用於對列表(Lists)和集合(Collections)數據進行提取、過濾和排序。本文分享在代碼中最有用的10個lambda表達式的使用方法,這些例子都短小精悍,將幫助你快速學會lambda表達式。
  • Java8 lambda表達式
    如何在正確的場合使用lambda表達式?下面有幾個使用lambda表達式的例子①展示了在沒有參數的情況下如何使用lambda,可以使用一對空的小括號來表示沒有參數,這是一個實現了Runnable的lambda的表達式,該接口只有一個方法run(),該方法不接受任何參數,且返回void.
  • Python每天一分鐘:lambda表達式 (匿名函數)及用法詳解
    ] : 表達式根據其語法格式可以得到lambda 表達式的兩個要點:lambda 表達式必須使用 lambda 關鍵字定義。* y即函數定義可以使用簡化方式:當函數體只有一行代碼時,可直接把函數的代碼體放在與函數頭同一行。
  • Java lambda表達式
    Java lambda表達式是Java 8新特性。它是步入Java函數式編程的第一步。因此,Java lambda表達式是創建時不屬於任何類的函數。它可以像一個對象一樣傳遞,並按要求執行。如果lambda表達式匹配參數類型(在這種情況下,是StateChangeListenerinterface),lambda表達式將轉換成實現該參數接口的函數。Java lambda表達式只能在匹配的類型只是單方法接口的時候使用。在上面的示例中,使用lambda表達式作為參數,參數類型為StateChangeListener接口。這個接口只有一個方法。
  • python之lambda函數使用
    lambda [arg1 [,arg2,argn]]:expressionargs指的是參數,expression指條件表達式,根據參數,進行條件表達後輸出相應內容。二,lambda簡單使用def detail(x,y): return x*ys = lambda x,y:x*yprint(s(3,3))以上對比我們可以看出如果我們想計算兩個數的乘積,需要定義一個函數,傳入兩個形參,然而lambda也是直接傳入兩個形參。後面使用冒號,寫入表達式,即可得到我們所需要的結果。
  • Python中lambda表達式的常見用法
    ,即沒有函數名字的臨時使用的小函數。lambda表達式只可以包含一個表達式,不允許包含其他複雜的語句,但在表達式中可以調用其他函數,並支持默認值參數和關鍵參數,該表達式的計算結果相當於函數的返回值。下面的代碼演示了不同情況下lambda表達式的應用。
  • Python中的Lambda表達式
    Lambda表達式當我們需要做一些簡單的事情並且更希望快速完成工作而不是正式命名函數時,Lambda表達式是理想的選擇。Lambda表達式也稱為匿名函數。Python中的Lambda表達式是聲明小型匿名函數的一種簡短方式(沒有必要為Lambda函數提供名稱)。
  • Java 8新特性:學習如何使用Lambda表達式(一)
    是對這樣的入參數據進行處理(String firstStr, String secondStr),使用這樣的 Integer.compare(firstStr.length(),secondStr.length()) 代碼片斷。於是,有了我們第一個lambda表達式!此表達式指定代碼塊和必須傳遞給代碼塊的變量。
  • 不要在Python中編寫 lambda 表達式了
    當經驗豐富的 Python 程式設計師看到一個lambda 表達式時, 他們知道他們正在使用一個僅在一個地方有效的函數, 並且只做一件事情.如果你曾經在 JavaScript 中使用過匿名函數, 那麼Python 中的 lambda 表達式與之相同, 除了具有更多限制以及與傳統函數完全不同的語法.
  • Java 8新特性:學習如何使用Lambda表達式(二)
    lambda表達式由三個部分組成:代碼塊參數自由變量不是參數,也沒有在lambda中定義在我們的案例中有兩個自由變量, text和 count。表示lambda的數據結構必須存儲它們的值,「嗨!」 他們說這些值是由lambda表達式捕獲的。(如何完成取決於實現。
  • C++ lambda表達式簡介及作用
    C++ lambda表達式簡介及作用C/C++的可調用對象在C語言中,可調用對象僅有函數指針。捕獲列表,捕獲列表是lambda表達式與普通函數的一個較為明顯的區別,主要是用於lambda表達式函數體中使用外層作用域中的變量的情況,捕獲可以以值捕獲或以引用捕獲,效果見名知意。
  • Python中的lambda函數
    匿名函數是指沒有聲明函數名稱的函數。儘管它們在語法上看起來不同,lambda函數的行為方式與使用def關鍵字聲明的一般函數相同。以下是Python中 lambda函數的特點:在本文中,我們將詳細討論Python中的lambda函數,並演示使用它們的例子。
  • 自從學會Java中的lambda表達式和函數式編程技巧,再也不用加班了!
    題記本文將分享如何在Java程序中使用lambda表達式和函數式編程技巧在Java SE 8之前,匿名類通常用於將功能傳遞給方法。這種做法混淆了原始碼,使代碼難以理解***。Java 8通過引入lambda來解決這個問題。本教程首先介紹lambda的語言特性,然後詳細的介紹了如何使用lambda表達式並根據目標類型進行函數式編程。
  • C++核心準則​T.141:如果你需要只在一個地方使用的簡單的函數對象,使用無名的lambda表達式
    T.141: Use an unnamed lambda if you need a simple function object
  • C++中的lambda函數
    作者:  2019信息與計算科學專業   楊澤天lambda函數是C++11中的匿名函數,又叫lambda表達式,叫lambda表達式更好理解,因為函數是不可以在函數中定義的,表達式可以。lambda表達式,可以簡化編程工作。
  • 一文帶你認識 C++ 中的 Lambda 函數
    因為 lambda並不總是函數指針,它一個表達式。但是為了簡單起見,我一直都稱它為函數。那麼在本文中,我將會交替使用lambda函數和表達式來稱呼。Lambda函數是一段簡短的代碼片段,它具有以下特點:(1)不值得命名(無名,匿名,可處理等,無論您如何稱呼)(2)不會重複使用換句話說,它只是語法糖。
  • Lambda 表達式,簡潔優雅就是生產力!
    為了避免後來的人在這個接口中增加接口函數導致其有多個接口函數需要被實現,變成"非函數接口」,我們可以在這個上面加上一個聲明@FunctionalInterface, 這樣別人就無法在裡面添加新的接口函數了:這樣,我們就得到了一個完整的Lambda表達式聲明:2Lambda表達式有什麼作用
  • java8 之 lambda 表達式簡介
    Lambda 表達式的本質只是基於接口的語法糖(語法糖:指在計算機語言中添加的某種語法,這種語法對語言的功能沒有影響,但是更方便程式設計師使用),而 Stream 的引入,使其對集合的操作變的更加方便和強大。lambda表達式格式: (param1, param2, ...) -> expression。