不論資料多雜亂,在做資料分析之前,總是先要整理成關聯式資料,這一段一直是分析中最麻煩也最惱人的一段,特別是當資料量大的時候,其中可能問題又更多了.這次遇到的麻煩是要固定將機器每天的 Log 檔轉成關聯式資料,聽起來不難,是很常見的需求,但是看了資料格式之後整個傻眼.
這樣的格式麻煩點在:
- 非一般的資料格式: 既不是關聯式資料,也不是 Json 格式(真的很想打設計這種 log 出來的人),沒辦法輕易地整理.
- 分隔符號不固定: 雖然後面的資料是用 = 做為key和value分隔,但是前面四個欄位不是,表示資料要分開處理.
- 資料欄位內有空格: 如果預設用" "當做每個欄位的分隔符號,會在這些內部有空格的地方吃了大虧,所以要另外寫工具來區別這種情況.
- 每筆資料有的key不一致: 這是最麻煩的事.例如有些筆資料有 location 這個 key ,但是有些資料沒有...,連 null 都不給.所以就算你處理完上面三件事,每筆資料的欄位長度還是不一樣.
以下會逐步說明如何處理上述這幾個地方.
就處理資料邏輯來說,會先把資料根據欄位切開來,然後再把對應的直塞到欄位裡.但是這個資料因為每筆欄位不太一致,所以想說乾脆直接轉成 Json 來處理比較方便,因為我把所有東西都寫在同一航裡面,所以只好一起看這主要的部分:
用Spark 寫起來真的很簡單:
- 第一行的 map 用了一個自已寫的_space_split 工具來避免上面提到的第三點--把值裡面的空白切開.
- 第二行把每一個 Row 切成前面四個和後面剩下的
- 前面四個固定欄位直接人工塞 key 的名稱
- 剩下的就用 = 分隔,轉成Python 中的 Dictionary 物件
- encode 的用途在於原始資料預設 utf-8格式,在字串處理上會變成u'day',這樣的東西Spark 會沒辦法辨識成 Json 格式.
這一段完成之後已經將每個醜醜的 row 轉成 json 格式,至於每個 json 格式裡面的Key都不同沒有關係,交由 Spark 自己處理.因此我們透過 JsonRDD 讀取剛剛的檔案:
Spark 就會自動轉成DataFrame ,這時候可以用 printSchema() 和 show() 檢查一下欄位是不是正確,接著就可以用 write 快樂的轉成 parquet 存放了.
沒有留言:
張貼留言