Scala數據分析 Step:1=>解析xlsx
我是打算寫scala了。
做出這種決定的理由是充分的,各種par也是美滋滋。而且jvm上東西多(雖然數據分析模塊少得不行,而且包管理時下載速度真的揪心。
我是不知道除了spark有什麼好的數據分析模塊,但需求是剛性的。scala最新版本又是不支持spark最新版本的。
所以我要自己造點東西。像pandas 和dataframe 真的太舒服,我就比劃著來。
要分析數據,首先你要把數據拿出來額,就是csv/xlsx解析器。我到處找,而到處都在安利那個poi,恰好我覺得它api不止是有點丑,所以我就自己寫一個吧。
剛開始我想,無非讀入文件,然後尋找數據存儲的方式,把有用的數據整理出來。
但是當我打開xlsx文件後,我發現裡面都是全是256*256,然後我就查了一下。
經過探索,我發現xlsx可以解壓,解壓之後,裡面的東西就不是256*256了,取而代之的是一些.xml,.res.xml文件。
經過探索,我發現./xl/worksheets裡面的xml都是裝的xlsx分表的數據,然後觀察了一下數據組織方式。是這樣的:
注意到以下的tag<sheetData>n<row>n<c> => column, c.r => 單位格的位置n<v> => valuen
然後我就以為我完全掌握了規律。但其實如果單元格數據不是數字的話,數據會被放到另一個配置文件里。經過探索,這個配置文件在./xl/shareStrings.xml里。
<si>n<t> : 裡面就是數據源文件./xl/worksheets/*.xml被藏起來的字元串。源文件里的v映射到這裡的第v個字元串。n
嗯,這就是全部了。
然後我去查了一下網上關於java解壓文件的代碼,順便改寫了一下。
分析一下問題流程,大概是這樣的:
- 使用者調用對象xlsx
- 程序獲取文件,解壓之。
- 讀取數據文件,解析之。
- 將解析結果以合適形式返回。
- n個dataframe,每個dataframe是一個二維表,表的每一列數據類型不一致。類型應該為GenSeq[GenSeq[GenSeq[Any]]]。
- 之前想有沒有在一個Seq里放多種類型的方法,莎莎說讓我寫wrapper,但我想在使用dataframe時都是人在手工了,asInstanceOf就好,暫時不去管數據類型的存放
當然這只是讀取xlsx數據內容的東西。我寫的時候還留了一點別的抽象,雖然估計並不會再用到(逃
然後這堆scala代碼前幾天寫的,一堆這種
while (doAction) {};n
因為我不知道怎麼把把一個Stream弄成迭代器比如,像下面這樣
//zipin:java.util.zip.ZipInputStream n(for stream:java.util.zip.ZipEntry <- zipin) yield stream n//這個句子是錯的。 ZipInputStream 沒法這麼遍歷...ZipInputStream 要是有一個toIter就好了。。n
所以我
while (null!=lambdaExpr (zipin) ) {};//lambdaExpr里就寫文件處理...感覺非常非主流n
最後效果如下:
然後代碼在thautwarm/NumScala 大概分成三個模塊,其中很畸怪的那個NumScala.util.xlsx.unzipXlsxFile可讀性可能挺糟糕的。當時才算剛正式開始寫scala,懷著"像聊天一樣,代碼寫哪兒是哪兒"的想法,瘋狂打連招(現在的話估計我會用一堆 match any=> 233333這個東西打算最後做成一個數據分析+數值計算 一條龍。現在的jvm對科學研究者太不友好了(雖然我接觸的在北美搞nlp的,很多居然都寫java的也是沒誰了...),希望能夠把包管理什麼的變得傻瓜點,能讓大家把重心放到實驗本身。
推薦閱讀: