全力以赴地進入數(shù)據(jù)集是從事數(shù)據(jù)科學(xué)工作的任何人的使命之一。通常,這意味著要進行數(shù)字運算,但是當(dāng)我們的數(shù)據(jù)集主要基于文本時,我們該怎么辦?我們可以使用正則表達式。在本教程中,我們將仔細(xì)研究如何在Python中使用正則表達式(regex)。
正則表達式(regex)本質(zhì)上是文本模式,可用于自動搜索和替換文本字符串中的元素。這可以使清理和使用基于文本的數(shù)據(jù)集變得更加容易,從而省去了手動搜索大量文本的麻煩。
正則表達式可以在多種編程語言中使用,并且已經(jīng)存在很長時間了!
不過,在本教程中,我們將學(xué)習(xí)Python中的正則表達式,因此需要基本熟悉關(guān)鍵的Python概念,例如if-else語句,while和for循環(huán)等。在本教程結(jié)束時,您將熟悉Python regex的工作原理,并能夠使用Python regex模塊中的基本模式和功能re來分析文本字符串。您還將獲得有關(guān)正則表達式如何與熊貓配合使用以處理大型文本語料庫的介紹。
讓我們深入研究有關(guān)每個人最不喜歡的電子郵件類型的一些數(shù)據(jù):垃圾郵件和欺詐。
我們的任務(wù):分析垃圾郵件
在本教程中,我們將使用Kaggle的欺詐電子郵件語料庫。它包含1998年至2007年之間發(fā)送的數(shù)千種網(wǎng)絡(luò)釣魚電子郵件。它們非常有趣,易于閱讀。
您可以在這里找到完整的語料庫。但是,我們將從使用一些電子郵件學(xué)習(xí)基本的正則表達式命令開始。如果需要,您也可以使用我們的測試文件,也可以在完整的語料庫中嘗試使用。
介紹Python的Regex模塊
首先,我們將通過打開測試文件,將其設(shè)置為只讀并讀取來準(zhǔn)備數(shù)據(jù)集。我們還將其分配給變量fh(用于“文件句柄”)。
請注意,我們在目錄路徑之前加r。此技術(shù)將字符串轉(zhuǎn)換為原始字符串,這有助于避免某些機器讀取字符的方式引起的沖突,例如Windows上目錄路徑中的反斜杠。
現(xiàn)在,假設(shè)我們要找出電子郵件的來源。我們可以自己嘗試使用原始Python:
但這并沒有給我們確切的需求。如果您看一下我們的測試文件,我們可以找出原因并修復(fù)它,但是,讓我們使用Python的re模塊并使用正則表達式來做吧!
我們將從導(dǎo)入Python的re模塊開始。然后,我們將使用一個名為的函數(shù)re.findall(),該函數(shù)返回在正在查看的字符串中定義的模式的所有實例的列表。
外觀如下:
這與原始Python的長度基本相同,但這是因為這是一個非常簡單的示例。您嘗試做的越多,Python正則表達式就可以為您節(jié)省更多的精力。
在繼續(xù)之前,讓我們仔細(xì)看看re.findall()。此函數(shù)采用形式為的兩個參數(shù)re.findall(pattern, string)。在這里,pattern代表我們要查找的子字符串,并string代表我們要在其中查找的主字符串。主字符串可以包含多行。在這種情況下,我們讓它fh使用選定的電子郵件來搜索所有文件。
該.*是一個字符串模式的簡寫。正則表達式通過使用這些速記模式來查找文本中的特定模式而起作用,因此讓我們看一下其他一些常見示例:
常見的Python正則表達式模式
我們re.findall()上面使用的模式包含一個完整拼寫的字符串"From:"。當(dāng)我們確切地知道我們要查找的內(nèi)容(精確到實際字母以及它們是否為大寫或小寫)時,這很有用。如果我們不知道我們想要的字符串的確切格式,我們將會迷路。幸運的是,正則表達式具有解決此情況的基本模式。讓我們看看在本教程中使用的那些:
1)w匹配字母數(shù)字字符,表示az,AZ和0-9。它還與下劃線_和破折號-相匹配。
2)d 匹配數(shù)字,表示0-9。
3)s 匹配空白字符,包括制表符,換行符,回車符和空格字符。
4)S 匹配非空格字符。
5).匹配除換行符外的任何字符n。
掌握了這些正則表達式模式后,您將在繼續(xù)進行解釋的同時快速理解上面的代碼。
使用正則表達式模式
現(xiàn)在,我們可以.*在re.findall("From:.*", text)上面的行中解釋的用法。讓我們.先來看:
通過在.旁邊添加一個From:,我們可以在其旁邊查找另一個字符。因為.查找除以外的任何字符n,所以它捕獲了我們看不到的空格字符。我們可以嘗試更多的點來驗證這一點。
看起來加點確實為我們獲得了線的其余部分。但是,這很繁瑣,而且我們不知道要添加多少點。這是星號符號*出現(xiàn)的位置。
*匹配模式左側(cè)的零個或多個實例。這意味著它將尋找重復(fù)模式。當(dāng)我們尋找重復(fù)的模式時,我們說搜索是“貪婪的”。如果我們不尋找重復(fù)的模式,則可以將搜索稱為“非貪婪”或“懶惰”。
讓我們構(gòu)建一個貪婪的搜索.用*。
因為*匹配在其左側(cè)指示的模式的零個或多個實例,并且.位于此處的左側(cè),所以我們能夠獲取From:字段中的所有字符,直到行尾。這將用精美簡潔的代碼打印出整行。
我們甚至可以更進一步,僅隔離名稱。讓我們使用它re.findall()來返回包含模式的行列表,"From:.*"就像之前一樣。match為了整潔,我們將其分配給變量。接下來,我們將遍歷列表。在每個循環(huán)中,我們將re.findall再次執(zhí)行,匹配第一個引號以僅選擇名稱:
注意,我們在第一個引號旁邊使用了反斜杠。反斜杠是一個特殊字符,用于轉(zhuǎn)義其他特殊字符。例如,當(dāng)我們想將引號用作字符串文字而不是特殊字符時,可以使用反斜杠將其轉(zhuǎn)義,例如:\"。如果我們不使用反斜杠轉(zhuǎn)義上面的模式,它將變?yōu)?quot;".*"",Python解釋器將其讀取為兩個空字符串之間的句點和星號。它將產(chǎn)生錯誤并破壞腳本。因此,至關(guān)重要的是我們在這里用反斜杠將引號引起來。
匹配第一個引號后,.*獲取行中的所有字符,直到下一個引號也被轉(zhuǎn)義為模式。這使我們得到的名稱只是帶引號的名稱。該名稱也打印在方括號中,因為re.findall返回的匹配項在列表中。
如果我們想要電子郵件地址怎么辦?
看起來很簡單,不是嗎?僅模式不同。讓我們來看一看。
這是我們僅匹配電子郵件地址的前部分的方式:
電子郵件總是包含一個@符號,因此我們從它開始。電子郵件中@符號前的部分可能包含字母數(shù)字字符,這w是必需的。但是,由于某些電子郵件包含句點或破折號,所以這還不夠。我們添加S以查找非空白字符。但是,w\S只會得到兩個字符。添加*以查找重復(fù)。因此,模式的前部如下所示:\w\S*@。
現(xiàn)在查看@符號后面的模式:
域名通常包含字母數(shù)字字符,句點和短劃線,因此a .可以。為了使它更貪婪,我們使用擴展了搜索范圍*。這使我們可以匹配任何字符,直到行尾。
如果我們仔細(xì)觀察這條線,會發(fā)現(xiàn)每封電子郵件都封裝在尖括號<和>中。我們的模式.*包括右括號>。讓我們對其進行補救:
電子郵件地址以字母數(shù)字字符結(jié)尾,因此我們將模式設(shè)置為w。因此,在@符號后面有.*\w,這表示我們想要的模式是一組以字母數(shù)字字符結(jié)尾的任何類型的字符。不包括>。
因此,我們的完整電子郵件地址格式如下所示:\w\S*@.*\w。
!這需要花費很多時間。接下來,我們將介紹一些通用re功能,這些功能在開始重新組織語料庫時將非常有用。
常用的Python正則表達式函數(shù)
re.findall()無疑是有用的,但它不是我們可以使用的唯一內(nèi)置函數(shù)re:
1)re.search()
2)re.split()
3)re.sub()
在使用它們?yōu)槲覀兊臄?shù)據(jù)集添加一些順序之前,讓我們一一看一下。
研究()
While re.findall()匹配字符串中某個模式的所有實例并在列表中返回它們,re.search()匹配字符串中一個模式的第一個實例,并將其作為re匹配對象返回。
像一樣re.findall(),re.search()也有兩個參數(shù)。第一個是要匹配的模式,第二個是要在其中找到模式的字符串。在這里,我們將結(jié)果分配給match變量以保持整潔。
由于re.search()返回re匹配對象,因此無法通過直接打印來顯示名稱和電子郵件地址。相反,我們必須首先對該group()函數(shù)應(yīng)用該函數(shù)。我們已經(jīng)在上面的代碼中打印了這兩種類型。如我們所見,group()將match對象轉(zhuǎn)換為字符串。
我們還可以看到,打印match顯示的屬性超出字符串本身,而打印match.group()僅顯示字符串。
re.split()
假設(shè)我們需要一種快速的方法來獲取電子郵件地址的域名。我們可以通過三個正則表達式操作來做到這一點,如下所示:
第一行很熟悉。我們返回一個字符串列表,每個字符串包含F(xiàn)rom:字段的內(nèi)容,并將其分配給變量。接下來,我們遍歷列表以查找電子郵件地址。同時,我們循環(huán)訪問電子郵件地址,并使用該re模塊的split()功能將每個地址切成兩半,用@符號作為分隔符。最后,我們打印它。
re.sub()
另一個方便的re功能是re.sub()。就像函數(shù)名稱所暗示的那樣,它替換字符串的一部分。一個例子:
我們之前已經(jīng)在第一行和第二行看到了任務(wù)。在第三行,我們re.sub()在上應(yīng)用address,這是From:電子郵件標(biāo)題中的完整字段。
re.sub()需要三個參數(shù)。第一個是要替換的子字符串,第二個是我們要替換的字符串,第三個是主字符串本身。
正則表達式與pandas
現(xiàn)在,我們掌握了Python正則表達式的基礎(chǔ)知識。但是通常對于數(shù)據(jù)任務(wù),我們實際上并沒有使用原始的Python,而是使用了pandas庫?,F(xiàn)在,將我們的正則表達式技能帶入熊貓工作流程,將其提升到一個新的水平。
如果您以前從未使用過熊貓,請不要擔(dān)心。我們將逐步遍歷代碼,以免您迷路。但是,如果您想更詳細(xì)地了解熊貓,請查看我們的熊貓教程或我們提供的有關(guān)numpy和熊貓的完全交互式課程。
使用Python Regex和Pandas對電子郵件進行排序
我們的語料庫是一個包含數(shù)千封電子郵件的單個文本文件(不過,同樣,在本教程中,我們使用的是一個只有兩個電子郵件的較小文件,因為在整個語料庫上打印正則表達式工作的結(jié)果會使這篇文章過長)。
我們將使用正則表達式和熊貓將每封電子郵件的各個部分分類為適當(dāng)?shù)念悇e,以便可以更輕松地閱讀或分析語料庫。
我們將每封電子郵件分為以下類別:
1)sender_name
2)sender_address
3)recipient_address
4)recipient_name
5)date_sent
6)subject
7)email_body
這些類別中的每一個都將成為我們的熊貓數(shù)據(jù)框(即我們的表格)中的一列。這將使我們更輕松地分別處理和分析每個列。
我們將繼續(xù)處理我們的小樣本,但是值得重申的是,正則表達式使我們可以編寫更簡潔的代碼。簡潔的代碼減少了我們的機器必須執(zhí)行的操作數(shù)量,從而加快了我們的分析過程。使用我們的兩封電子郵件的小文件,并沒有太大的區(qū)別,但是,如果您嘗試使用和不使用正則表達式來處理整個語料庫,您將開始看到其優(yōu)勢!
準(zhǔn)備腳本
首先,讓我們導(dǎo)入所需的庫,然后再次打開文件。
除了re和之外pandas,我們email還將導(dǎo)入Python的軟件包,這將有助于電子郵件的正文。僅使用正則表達式時,電子郵件的主體相當(dāng)復(fù)雜。它甚至可能需要足夠的清理才能保證有自己的教程。因此,我們將使用完善的email軟件包來節(jié)省一些時間,讓我們專注于學(xué)習(xí)正則表達式。
我們還創(chuàng)建了一個空列表emails,用于存儲字典。每本詞典將包含每封電子郵件的詳細(xì)信息。
現(xiàn)在,讓我們開始應(yīng)用正則表達式!
注意:為簡潔起見,我們剪裁了上面的打印輸出。如果您在自己的機器上打印此文件,它將顯示其中包含的所有內(nèi)容,contents而不是...像上面那樣結(jié)束。
我們使用re模塊的split函數(shù)將整個文本塊分割fh為單獨的電子郵件列表,然后將其分配給變量contents。這很重要,因為我們希望通過使用for循環(huán)遍歷列表來逐一處理電子郵件。但是,我們?nèi)绾沃腊醋址指?quot;From r"?
我們之所以知道這一點,是因為在編寫腳本之前我們已經(jīng)查看了文件。我們不必細(xì)讀其中的數(shù)千封電子郵件。只是前幾個,看看數(shù)據(jù)的結(jié)構(gòu)是什么樣子。只要有可能,最好在開始使用代碼之前先關(guān)注實際數(shù)據(jù),因為您經(jīng)常會發(fā)現(xiàn)諸如此類的有用功能。
我們已經(jīng)截取了原始文本文件的屏幕截圖:
電子郵件以“ From r”開頭
綠色方框是第一封電子郵件。藍(lán)色方框是第二封電子郵件。如我們所見,這兩封電子郵件均以開頭"From r",并以紅色框突出顯示。
我們在本教程中使用欺詐電子郵件語料庫的原因之一是,當(dāng)數(shù)據(jù)雜亂無章,不熟悉且沒有文檔時,我們不能僅僅依靠代碼來整理數(shù)據(jù)。這將需要一雙人眼。正如我們剛剛顯示的,我們必須研究語料庫本身以研究其結(jié)構(gòu)。
像這樣雜亂無章的數(shù)據(jù)可能需要大量清理。例如,即使我們使用本教程將要構(gòu)建的完整腳本來計算此集合中的3977封電子郵件,但實際上還有更多。某些電子郵件實際上并不以開頭"From r",因此不會單獨計算。(不過,為了簡潔起見,我們將繼續(xù)處理該問題,并用分隔所有電子郵件"From r"。)
還要注意,我們contents.pop(0)用來擺脫列表中的第一個元素。這是因為"From r"字符串在第一封電子郵件之前。拆分該字符串后,它將在索引0處生成一個空字符串。我們將要編寫的腳本是為電子郵件設(shè)計的。如果我們嘗試在空字符串上使用它,則可能會引發(fā)錯誤。擺脫空字符串可以使我們避免破壞腳本。
使用For循環(huán)獲取每個名稱和地址
接下來,我們將使用contents列表中的電子郵件。
在上面的代碼中,我們使用for循環(huán)來遍歷,contents因此我們可以依次處理每封電子郵件。我們創(chuàng)建了一個詞典,emails_dict其中包含每封電子郵件的所有詳細(xì)信息,例如發(fā)件人的地址和姓名。實際上,這些是我們發(fā)現(xiàn)的第一批物品。
這是一個三步過程。首先從尋找From:領(lǐng)域開始。
在第1步中,我們From:使用re.search()函數(shù)查找整個字段。該.裝置除了任何字符n,并且*其延伸到行的結(jié)尾。然后,我們將其分配給變量sender。
但是,數(shù)據(jù)并不總是那么簡單。它可能包含驚喜。例如,如果沒有From:字段怎么辦?該腳本將引發(fā)錯誤并中斷。我們在步驟2中避免了這種情況下的錯誤。
為了避免由于缺少From:字段而導(dǎo)致的錯誤,我們使用一條if語句來檢查sendernot None。如果是,我們分配s_email和s_name的值,None以便腳本可以繼續(xù)運行而不是意外中斷。
如果您在自己的文件中使用本教程,則可能已經(jīng)意識到使用正則表達式會變得混亂。例如,這些if-else語句是在編寫主體時對主體使用反復(fù)試驗的結(jié)果。編寫代碼是一個反復(fù)的過程。值得注意的是,即使本教程看起來很簡單,實際實踐也需要進行更多的實驗。
在第2步中,我們使用之前的regex模式\w\S*@.*\w,該模式與電子郵件地址匹配。
我們將對名稱使用其他策略。每個名稱都由左側(cè):子字符串的冒號()"From:"和<右側(cè)電子郵件地址的左尖括號()界定。因此,我們使用它:.*<來查找名稱。我們擺脫:并<從每個結(jié)果的時刻。
現(xiàn)在,讓我們打印出代碼的結(jié)果以查看它們的外觀。
同樣,我們有匹配對象。每次我們將re.search()字符串應(yīng)用于字符串時,都會生成匹配對象。我們必須將它們變成字符串對象。
我們這樣做之前,記得,如果沒有From:現(xiàn)場,sender將具有的價值None,因此也將s_email和s_name。因此,我們必須再次檢查這種情況,以便腳本不會意外中斷。讓我們看看如何首先構(gòu)建代碼s_email。
在步驟3A中,我們使用一條if語句檢查s_emailnot None,否則它將引發(fā)錯誤并破壞腳本。
然后,我們只需將s_emailmatch對象轉(zhuǎn)換為字符串并將其分配給sender_email變量。我們將其添加到emails_dict字典中,這將使我們?nèi)蘸髮⒓?xì)節(jié)轉(zhuǎn)換為pandas數(shù)據(jù)框變得異常容易。
我們s_name在步驟3B中所做的幾乎完全相同。
正如我們以前那樣,我們首先檢查s_name是不是None在步驟3B。
然后,在將字符串分配給變量之前,我們兩次使用re模塊的re.sub()函數(shù)。首先,我們刪除冒號和它與名稱之間的所有空白字符。我們:s*用一個空字符串代替""。然后,我們刪除空格字符和名稱另一邊的尖括號,再次用空字符串替換它。最后,在將字符串分配給之后sender_name,我們將其添加到字典中。
讓我們檢查一下結(jié)果。
完善。我們已經(jīng)隔離了電子郵件地址和發(fā)件人的姓名。我們還將它們添加到字典中,該字典將很快投入使用。
現(xiàn)在我們已經(jīng)找到了發(fā)件人的電子郵件地址和名稱,我們將執(zhí)行完全相同的步驟來獲取字典的收件人的電子郵件地址和名稱。
首先,我們找到To:領(lǐng)域。
接下來,我們搶先在場景recipient是None。
如果recipient不是None,則用于re.search()查找包含電子郵件地址和收件人姓名的匹配對象。否則,我們傳遞r_email和r_name的值None。
然后,將匹配對象轉(zhuǎn)換為字符串并將其添加到字典中。
由于From:和To:字段的結(jié)構(gòu)相同,因此我們可以對兩者使用相同的代碼。我們需要為其他字段定制略有不同的代碼。
獲取電子郵件的日期
現(xiàn)在確定發(fā)送電子郵件的日期。
我們Date:為From:和To:字段獲取具有相同代碼的字段。
并且,就像我們對這兩個字段所做的一樣,我們檢查Date:分配給date_field變量的字段是否不是None。
我們已經(jīng)打印了出來,date_field.group()以便我們可以更清楚地看到字符串的結(jié)構(gòu)。它包括日期,DD MMM YYYY格式的日期和時間。我們只想要日期。日期的代碼與姓名和電子郵件地址基本相同,但更為簡單。也許唯一令人困惑的是正則表達式模式\d+\s\w+\s\d+。
日期以數(shù)字開頭。因此,我們用d它來解釋它。但是,作為日期的DD部分,它可以是一位或兩位數(shù)字。在這里+變得重要。在Python正則表達式中,+匹配其左側(cè)1個或多個模式實例。d+因此,無論日期是DD還是一兩位數(shù)字,它都將與日期的DD部分匹配。
在那之后,有一個空間。這是由占的s,它查找空白字符。因此,該月由三個字母組成w+。然后它撞到另一個空間s。年份由數(shù)字組成,因此我們d+再次使用。
完整模式\d+\s\w+\s\d+起作用的原因是它是一個精確的模式,在兩側(cè)均以空格字符為界。
接下來,我們None像以前一樣檢查值。
如果date不是None,則將其從匹配對象轉(zhuǎn)換為字符串,并將其分配給變量date_sent。然后,將其插入字典中。
在繼續(xù)之前,我們應(yīng)該注意一個關(guān)鍵點。+并且*看起來相似,但它們可以產(chǎn)生非常不同的結(jié)果。讓我們以日期字符串為例。
如果使用*,則將匹配零個或多個匹配項。+匹配一個或多個事件。我們已經(jīng)打印了兩種情況的結(jié)果。有很大的不同。如您所見,+獲取完整日期,而*獲取空格和數(shù)字31。
接下來,是電子郵件的主題行。
獲取電子郵件主題
和以前一樣,我們使用相同的代碼和代碼結(jié)構(gòu)來獲取所需的信息。
現(xiàn)在我們對Python正則表達式的使用越來越熟悉了,不是嗎?它與以前的代碼大致相同,不同之處在于,我們"Subject: "用空字符串代替僅獲取主題本身。
獲取電子郵件的正文
要插入字典的最后一項是電子郵件的正文。
將標(biāo)頭與電子郵件正文分開是一項非常復(fù)雜的任務(wù),尤其是當(dāng)許多標(biāo)頭以一種或另一種方式不同時。在原始的無組織數(shù)據(jù)中很少發(fā)現(xiàn)一致性。對我們來說幸運的是,這項工作已經(jīng)完成。Python的email軟件包非常擅長此任務(wù)。
請記住,我們已經(jīng)較早導(dǎo)入了該軟件包?,F(xiàn)在,我們將其message_from_string()功能應(yīng)用于item,以將完整的電子郵件轉(zhuǎn)換為emailMessage對象。Message對象由標(biāo)頭和有效負(fù)載組成,它們分別對應(yīng)于電子郵件的標(biāo)頭和正文。
接下來,我們將其get_payload()功能應(yīng)用于Message對象。此功能隔離電子郵件的正文。我們將其分配給變量body,然后將其插入到emails_dict鍵下的字典中"email_body"。
為什么使用電子郵件軟件包而不是正文
您可能會問,為什么使用emailPython軟件包而不是regex?這是因為目前還沒有很好的方法來處理Python正則表達式,而這不需要大量的清理工作。這意味著可能需要另外一份教程。
值得檢查一下我們?nèi)绾巫龀鲞@樣的決定。但是,我們需要先了解[ ]正則表達式中的方括號,然后才能這樣做。
[ ]匹配放置在其中的任何字符。例如,如果我們要查找"a","b"或"c"字符串,則可以將其[abc]用作模式。我們上面討論的模式也適用。[\w\s]會找到字母數(shù)字或空格字符。例外是.,它成為方括號內(nèi)的文字周期。
現(xiàn)在,我們可以更好地了解我們是如何決定使用電子郵件軟件包的。
窺視數(shù)據(jù)集可發(fā)現(xiàn)電子郵件標(biāo)題在字符串"Status: 0"或處停止"Status: R0",并"From r"在下一封電子郵件的字符串前結(jié)束。因此,我們可以Status:\s*\w*\n*[\s\S]*From\sr*用來僅獲取電子郵件正文。[\s\S]*適用于大塊的文本,數(shù)字和標(biāo)點符號,因為它可以搜索空白或非空白字符。
不幸的是,有些電子郵件包含多個"Status:"字符串,而另一些則不包含"From r",這意味著我們會將電子郵件拆分成多于或少于電子郵件列表中詞典的數(shù)量。它們與我們已經(jīng)擁有的其他類別不匹配。使用熊貓時,這會產(chǎn)生問題。因此,我們決定利用該email軟件包。
創(chuàng)建詞典列表
最后,將字典追加emails_dict到emails列表中:
我們可能要emails在此時打印列表以查看其外觀。如果您只是一直在使用我們的小樣本文件,那么這將是反高潮的,但是在整個語料庫中,您將看到正則表達式的強大功能!
我們還可以print(len(emails_dict))查看列表中有多少個詞典,因此還有電子郵件。如前所述,整個語料庫包含3977。
這是完整的代碼:
如果使用我們的示例文本文件運行它,將會得到以下結(jié)果:
我們已經(jīng)打印出emails列表中的第一項,它顯然是帶有鍵和值對的字典。因為我們使用了for循環(huán),所以每個字典都具有相同的鍵但值不同。
我們已替換為item,"email content here"以便我們不會打印出電子郵件的全部內(nèi)容并阻塞屏幕。如果您要使用實際數(shù)據(jù)集在家打印此文件,則會看到整個電子郵件。
用熊貓?zhí)幚頂?shù)據(jù)
有了列表中的詞典,我們使熊貓圖書館的工作變得無比輕松。每個鍵將成為列標(biāo)題,每個值將成為該列中的一行。
我們要做的就是應(yīng)用以下代碼:
通過這一行,我們emails使用pandas DataFrame()函數(shù)將字典列表轉(zhuǎn)換為數(shù)據(jù)框。我們也將其分配給變量。
而已。現(xiàn)在,我們有了一個復(fù)雜的熊貓數(shù)據(jù)框。這實際上是一個整潔的表格,其中包含我們從電子郵件中提取的所有信息。
讓我們看一下前幾行。
該dataframe.head()函數(shù)僅顯示前幾行,而不顯示整個數(shù)據(jù)集。這需要一個論點。一個可選參數(shù)允許我們指定要顯示多少行。在這里,n=3讓我們查看三行。
我們還可以精確地找到我們想要的東西。例如,我們可以找到從特定域名發(fā)送的所有電子郵件。但是,讓我們學(xué)習(xí)一種新的正則表達式模式,以提高找到所需項目的精度。
管道符號會|在其任一側(cè)尋找字符。例如,a|b尋找a或b。
|可能看起來與相同[ ],但是它們確實有所不同。假設(shè)我們要匹配要么"crab","lobster"或"isopod"。使用crab|lobster|isopod會比有意義[crablobsterisopod],不是嗎?前者將尋找每個單詞,而后者將尋找每個字母。
現(xiàn)在,我們|來查找從一個或另一個域名發(fā)送的所有電子郵件。
我們在這里使用了相當(dāng)長的代碼。讓我們從內(nèi)而外開始。
emails_df['sender_email']選擇標(biāo)記為的列sender_email。接下來,str.contains(epatra|spinfinder)返回True是否在該列中找到子字符串"epatra"或"spinfinder"。最后,外部emails_df[]返回行的視圖,其中該sender_email列包含目標(biāo)子字符串。好漂亮!
我們也可以查看來自各個單元的電子郵件。為此,我們經(jīng)歷了四個步驟。在步驟1中,我們找到"sender_email"列包含字符串的行的索引"@spinfinder"。注意我們?nèi)绾问褂谜齽t表達式來執(zhí)行此操作。
在步驟2中,我們使用索引查找電子郵件地址,該loc[]方法作為具有多個不同屬性的Series對象返回該電子郵件地址。我們在下面將其打印出來以查看其外觀。
在第3步中,我們從系列對象中提取電子郵件地址,就像從列表中提取項目一樣。您可以看到它的類型現(xiàn)在是class。
步驟4是提取電子郵件正文的位置。
在步驟4中,emails_df['sender_email'] == "bensul2004nng@spinfinder.com"找到該sender_email列包含value 的行"bensul2004nng@spinfinder.com"。接下來,['email_body'].values查找email_body同一行中的列的值。最后,我們打印出該值。
如您所見,我們可以通過多種方式使用正則表達式,它也可以與大熊貓一起使用!如果您的正則表達式工作包含大量的反復(fù)試驗,請不要氣,,尤其是在您剛剛?cè)腴T時!
其他資源
自從幾年前正則表達式從生物學(xué)躍升為工程學(xué)以來,正則表達式已取得了巨大的發(fā)展。如今,正則表達式已在不同的編程語言中使用,其中除了其基本模式之外還有一些變體。我們已經(jīng)學(xué)習(xí)了很多Python正則表達式,并且如果您想將它提高到一個新的水平,那么我們的Python數(shù)據(jù)清理高級課程可能是一個不錯的選擇。
您還可以在官方參考資料中找到一些幫助,例如Python 有關(guān)其模塊的文檔re。Google有更快的參考資料。
如果您愿意,也可以開始探索Python regex與其他形式的regex Stack Overflow帖子之間的區(qū)別。
如果您需要數(shù)據(jù)集進行試驗,則Kaggle和StatsModels很有用。
最后,這是我們制作的Regex速查表,它也非常有用。
填寫下面表單即可預(yù)約申請免費試聽!怕錢不夠?可先就業(yè)掙錢后再付學(xué)費! 怕學(xué)不會?助教全程陪讀,隨時解惑!擔(dān)心就業(yè)?一地學(xué)習(xí),可推薦就業(yè)!
?2007-2022/ lb577.com 北京漫動者數(shù)字科技有限公司 備案號: 京ICP備12034770號 監(jiān)督電話:010-53672995 郵箱:bjaaa@aaaedu.cc