做資料分析必須瞭解的獲取資料與清洗資料技巧

weixin_34319817發表於2018-05-21


​點選關注 非同步圖書,置頂公眾號

每天與你分享 IT好書 技術乾貨 職場知識

​參與文末話題討論,每日贈送非同步圖書

——非同步小編

每個資料科學家都需要處理儲存在磁碟中的資料,這些資料涉及的格式有ASCII文字、PDF、XML、JSON等。此外,資料還可以儲存在資料庫表格中。在對資料進行分析之前,資料科學家首先要做的是從這些資料來源獲取各種格式的資料,並對這些資料進行清洗,去除其中的噪聲。今天推薦的圖書是《Java資料科學指南》一書,並從中節選第一章內容,從本文中我們將學習這些內容,即瞭解如何從不同資料來源獲取各種格式的資料。​

​在這一過程中,我們將用到外部Java庫(Java歸檔檔案,簡稱JAR檔案),這些庫的使用不僅限於本文,還貫穿於《Java資料科學指南》一書。這些庫由不同開發者或組織開發,方便了大家的使用。編寫程式碼時,我們會用到Eclipse IDE工具,它是Windows平臺下最好的整合開發環境,全書都會使用它。接下來,我們將講解如何匯入任意一個外部JAR檔案,以下各個部分將指導你把外部JAR檔案匯入到專案中,跟隨步驟動手去做即可。

對於一個Eclipse專案,你可以採用如下方法新增JAR檔案:首先依次單擊“Project|Build Path|Configure Build Path”,在Libraries選項卡中,單擊“Add External JARs”,選擇你想新增到專案的外部JAR檔案,如圖1-1所示。

1.2 使用Java從分層目錄中提取所有檔名 

這部分內容(以及後面各部分內容)是為那些想從複雜目錄結構中提取檔案路徑與名稱的資料科學家準備的,以方便進一步進行後續分析。這裡的複雜目錄結構是指在一個根目錄下包含大量目錄與檔案。

準備工作

開始之前,需要做如下準備工作。

1.建立複雜的目錄結構(目錄層數你自己決定)。

2.在其中一些目錄中建立文字檔案,而在另一些目錄中留空。

操作步驟

1.首先編寫一個static方法,即listFiles(File rootDir),它帶有一個File型別的引數,該引數可以是根目錄或起始目錄。這個方法將返回一系列檔案,這些檔案存在於引數所指定的根目錄(以及其他所有下級子目錄)中。

​2.然後,建立一個HashSet物件,用來包含檔案資訊。

​3.在建立好HashSet物件之後,要檢查引數指定的根目錄及其子目錄是否為null。當為null時,直接把HashSet物件返回即可,不需要進行進一步處理。

​4.接著,檢查根目錄中的每個目錄(或檔案),判斷它是檔案還是目錄。如果是檔案,就把它新增到HashSet中;如果是一個目錄,就遞迴地呼叫本方法,並把當前目錄路徑與名稱傳遞給它。

​5.最後,把HashSet返回給該方法的呼叫者。

​listFiles(File rootDir)方法的完整程式碼如下,包含執行該方法所需要的類與驅動方法。

​請注意,程式碼中的HashSet用來儲存檔案路徑與名稱。這意味著我們不會有任何重複項,這是因為Java中的Set這種資料結構不包含重複項。

1.3 使用Apache Commons IO從多層目錄中提取所有檔名

你可以使用前面一部分演示的操作步驟,採用遞迴方法把多層目錄中的檔名列出來。除此之外,我們還有另外一種更簡單、更方便的方法來完成它,那就是使用Apache Commons IO,並且只需編寫少量程式碼即可。

準備工作

開始之前,需要做如下準備。

1.本部分會用到一個名稱為Commons IO的Java庫,它來自於Apache基金會。全書中,我們會使用Commons IO 2.5版本,請從Commons官網下載JAR檔案。

2.在Eclipse中,把下載的JAR檔案包含到你的專案中(作為外部JAR檔案)。

操作步驟

1.建立listFiles方法,它帶有一個引數,用來指定層級目錄的根目錄。

​2.建立一個檔案物件,並把根目錄名傳遞給它。

​3.Apache Commons庫的FileUtils類中包含一個名稱為listFiles()方法。使用這個方法提取所有檔名,並且把它們放入一個帶有<File>泛型的列表變數中。使用TrueFileFilter.INSTANCE來匹配所有目錄。

​4.我們可以像下面這樣把檔名顯示在標準輸出中。由於我們把檔名放入了一個列表之中,所以我們可以通過某種方法對這些檔案中的資料進行進一步處理。

​5.關閉方法。

​完整程式碼包括方法程式碼、類程式碼,以及驅動方法,如下所示:

​如果你想把帶有一些特定副檔名的檔案列出來,還可以使用Apache Commons庫中的listFiles方法。但是這個方法的引數有些不同,它擁有3個引數,分別為檔案目錄、副檔名(String[])、遞迴與否。在這個庫中還有一個有趣的方法,即listFilesAndDirs(File directory, IOFileFilter fileFilter, FileFilter dirFilter),如果你想把檔案與目錄全部列出來,可以使用它。

1.4使用Java 8從文字檔案一次性讀取所有內容

在許多場合下,資料科學家所擁有的資料是文字格式的。我們有很多方法可以用來讀取文字檔案的內容,這些方法各具優缺點:一些方法執行起來耗時、耗記憶體,而另一些方法執行速度很快,也不需要消耗太多計算機記憶體;一些方法可以把全部文字內容一次性讀出,而另一些方法則只能一行行地讀取文字檔案。至於到底要選擇哪種方法,則取決於你所面對的任務,以及你決定採用何種方法來處理這個任務。

在這部分中,我們將演示使用Java 8把文字檔案的全部內容一次性讀出來的方法。

操作步驟

1.首先,建立一個String物件,用來儲存待讀取的文字檔案的目錄與名稱。

2.使用Paths類的get()方法,可以得到待讀檔案的路徑。get()方法的引數是String物件,用來指定檔名,它的輸出作為lines()方法的輸入。lines()方法包含於Files類之中,用來讀取一個檔案的所有行,並且返回Stream,也就是說,這個方法的輸出定向到一個Stream變數。因為我們的dummy.txt

檔案中包含字串資料,所以把Stream變數的泛型設定為String。整個讀取過程需要放入一個try...catch塊中,用來應對讀取過程中可能發生的異常,比如當試圖讀取的檔案不存在或已損壞時,就會丟擲異常。

下面程式碼用來把dummy.txt檔案中的內容全部顯示出來。在stream變數中包含著文字檔案的所有行,所以需要使用它的forEach()方法顯示出每行內容。

​1.5使用Apache Commons IO從文字檔案一次性讀取所有內容

在上一節中我們學習了使用Java8從文字檔案中一次性讀取所有內容,其實我們也可以使用Apache Commons IO API一次性讀取文字檔案的所有內容。

準備工作

開始之前,需要做如下準備。

1.本部分,我們會用到一個名為Apache Commons IO的Java庫。

2.在Eclipse中,把下載好的JAR檔案包含到你的專案中。

操作方法

1.假設你要讀取的檔案為dummy.txt,它位於C:/目錄之下。首先,需要建立一個檔案物件,用來訪問這個檔案,如下所示:

​2.接著,建立一個字串物件,用來儲存檔案中的文字內容。這裡我們要使用readFileToString()

方法,它來自於Apache Commons IO庫,是FileUtils類的一個成員方法。呼叫這個方法的方式有很多,但是現在,你只需知道我們要傳遞兩個引數給它,第一個引數是file物件,用來指定要讀取的檔案,第二個引數是檔案的編碼,在示例中,我們將其設定為UTF-8。

​3.只要使用上面兩行程式碼,我們就可以讀取文字檔案內容,並將它們存入一個String變數中。但是,你可不是一個普通的資料科學家,你比其他人要聰明得多。所以,你在上面兩行程式碼的前後又新增了幾行程式碼,用來處理Java方法丟擲的異常,比如你試圖讀取的檔案不存在或者已經損壞,就會觸發異常。為此,我們需要把上面兩行程式碼放入到一個try...catch塊之中,如下所示:

​1.6 使用Apache Tika提取PDF文字

在解析與提取資料時,最難搞的檔案型別之一是PDF檔案。有些PDF檔案甚至無法解析,因為它們有密碼保護,而其他一些則包含著掃描的文字與影像。所以,這種動態檔案型別有時會成為資料科學家的夢魘。本部分演示如何使用Apache Tika從PDF檔案提取文字,當然前提是PDF檔案沒有被加密,也沒有密碼保護,而只包含非掃描的文字。

準備知識

開始之前,需要先做如下準備。

1.下載Apache Tika 1.10 JAR檔案,並且將其作為外部Java庫包含到你的Eclipse專案中。

2.把任意一個未鎖定的PDF檔案儲存到C:/目錄之下,並且命名為testPDF.pdf。

操作步驟

1.建立一個名稱為convertPdf(String)的方法,它帶有一個字串引數,用來指定PDF檔名稱。

​2.建立一個輸入流,用來以位元組流的形式包含PDF資料。

​3.建立一個try塊,如下所示

​4.把檔案指派給剛剛建立好的stream。

​5.在Apache Tika包中包含著許多不同的解析器。如果你不知道該選用哪一個,或者說你還有其他型別的文件需要轉換,那麼你應該使用AutoDetectParser解析器,如下所示:

​6.建立一個handler,用來處理檔案的正文內容。請注意,建立時需要把建構函式的引數設為-1

。通常,Apache Tika會對處理的檔案進行限制,要求它至多包含100 000個字元。使用-1讓這個handler忽略這個限制。

​7.建立一個metadata物件。

​8.呼叫解析器物件的parser()方法,並把上面建立的這些物件傳遞給它。

​9.使用handler物件的tostring()方法,獲取從檔案中提取的正文文字。

​10.關閉try塊,並且新增catch與finally塊。最後,關閉整個方法,如下所示:

​下面程式碼包含convertPdf(String)方法的完整程式碼,以及相應的類與驅動方法。在呼叫convertPdf(String)方法時,你需要提供待轉換的PDF檔案的路徑與名稱,即把該方法的引數指定為C:/testPDF.pdf。

​ 1.7 使用正規表示式清洗ASCII文字檔案

ASCII文字檔案中通常會包含一些非必要的字元,這些字元通常產生於轉換過程中,比如把PDF轉換為文字或把HTML轉換為文字的過程中。並且,這些字元常常被看作噪聲,它們是資料處理的主要障礙之一。本部分,我們學習使用正規表示式為ASCII文字資料清洗一些噪聲的方法。

操作步驟

1.建立一個名為cleanText(String)的方法,它帶有一個String型別的引數,用來指定要清洗的文字。

​2.在你的方法中,新增如下幾行程式碼,而後把清洗後的文字返回,並關閉方法。在如下程式碼中,第一行程式碼用來去掉非ASCII字元,緊接的一行用來把連續的空格字元替換為單個空格字元。第三行用來清除所有ASCII控制字元。第四行用來去除ASCII非列印字元。最後一行用來從Unicode移除非列印字元。

​以下程式碼是方法的完整程式碼,包含相應類與驅動方法。

​1.8 使用Univocity解析CSV檔案

對資料科學家來說,另一種經常處理的檔案格式是CSV(逗號分隔)檔案,在這種檔案中資料之間通過逗號進行分隔。CSV檔案非常流行,因為大部分電子表格應用程式都可以讀取它,比如MS Excel。

本部分,我們將學習解析CSV檔案,以及處理所提取的資料點的方法。

準備工作

開始之前,需要先做如下準備。

1.下載Univocity JAR檔案,並將其作為外部庫新增到你的Eclipse專案中。

2.使用Notepad建立一個CSV檔案,它包含如下資料。建立好之後,把檔案的副檔名修改為.csv

,並把它儲存到C盤之下,即C:/testCSV.csv。

操作步驟

1.建立一個名為parseCsv(String)的方法,它帶有一個String型別的引數,用來指定待解析的檔名。

​2.而後建立一個配置物件,該物件用來提供多種配置選項。

​3.藉助於配置物件,你可以開啟解析器的自動檢測功能,讓它自動偵測輸入中包含何種行分隔符序列。

​4.建立一個RowListProcessor物件,用來把每個解析的行儲存在列表中。

​5.你可以使用RowProcessor來配置解析器,以對每個解析行的值進行處理。你可以在com.univocity.parsers.common.processor包中找到更多RowProcessors,但是你也可以自己建立。

​6.如果待解析的CSV檔案包含標題頭,你可以把第一個解析行看作檔案中每個列的標題。

​7.接下來,使用給定的配置建立一個parser例項。

​8.parser例項的parse()方法用來解析檔案,並把每個經過解析的行指定給前面定義的RowProcessor。

​9.如果解析中包含標題,則可使用如下程式碼獲取這些標題。

​10.隨後,你可以很容易地處理這個字串陣列,以獲取這些標題值。

11.另一方面,我們在列表中可以找到行值。只要使用一個for迴圈即可把列表列印出來,如下所示。

​12.最後,關閉方法。

​整個方法的完整程式碼如下所示:

​有很多采用Java編寫的CSV解析器。但是,相比較而言,Univocity是執行速度最快的一個。​

本文摘自《Java資料科學指南》

​《Java資料科學指南》

[加]魯什迪·夏姆斯(Rushdi Shams) 著

點選封面購買紙書


學習MLlib、DL4j和Weka等開源庫,掌握實用的Java資料科學技能

本書旨在通過Java程式設計來引導讀者更好地完成資料科學任務。本書通過9章內容,詳細地介紹了資料獲取與清洗、索引的建立和檢索資料、統計分析、資料學習、資訊的提取、大資料處理、深度學習、資料視覺化等重要主題。

今日互動

你對本書的看法?為什麼?截止時間5月31日17時,留言+轉發本活動到朋友圈,小編將抽獎選出3名讀者贈送紙書1本和2張e讀版80元非同步社群代金券,(留言點贊最多的自動獲得一張)。非同步圖書後臺回覆“5月新書”進入新書交流群,獲得第一手新書資訊, 點選此處直接參加活動。

推薦閱讀

2018年5月新書書單(文末福利)

2018年4月新書書單

非同步圖書最全Python書單

一份程式設計師必備的演算法書單

第一本Python神經網路程式設計圖書

​長按二維碼,可以關注我們喲

每天與你分享IT好文。


在“非同步圖書”後臺回覆“關注”,即可免費獲得2000門線上視訊課程;推薦朋友關注根據提示獲取贈書連結,免費得非同步e讀版圖書一本。趕緊來參加哦!

點選閱讀原文,購買《Java資料科學指南》

閱讀原文




相關文章