做數據分析必須了解的獲取數據與清洗數據技巧
來自專欄 非同步圖書
?點擊關注 非同步圖書,置頂公眾號
每天與你分享 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神經網路編程圖書?
http://weixin.qq.com/r/aUyJkZbEnMvjrdLy9xl7 (二維碼自動識別)
?長按二維碼,可以關注我們喲
每天與你分享IT好文。
在「非同步圖書」後台回復「關注」,即可免費獲得2000門在線視頻課程;推薦朋友關注根據提示獲取贈書鏈接,免費得非同步e讀版圖書一本。趕緊來參加哦!
點擊閱讀原文,購買《Java數據科學指南》
閱讀原文
推薦閱讀:
※探索模式——基於關聯規則的泰坦尼克號生存人員分析
※玩轉Pandas,讓數據處理更easy系列7
※數據分析師該這樣霸氣回應「0.00008的轉化也很好」的謬論
※Python 數據分析(五):數據的處理
※數據挖掘的知識大綱