查詢計算大文件的桌面程序工具

【摘要】

數(shù)據(jù)分析時构挤,難免會遇到內(nèi)存裝不下的大數(shù)據(jù)文件婶希,如何對大文件進行查詢計算?本文分析比較了幾種常用辦法的優(yōu)缺點孔轴,esProc SPL 是其中最適合數(shù)據(jù)分析師用于處理大文件的腳本。讓我們一起通過下面的文章一起來了解一下詳情吧~

什么是大文件碎捺?大文件是指大到計算機內(nèi)存不足以一次性讀入的文件路鹰。這種情況,直接使用桌面數(shù)據(jù)工具(比如 Excel)都無能為力了收厨,常常需要編寫程序來處理晋柱。而即使是寫程序,也必須是分批讀入進行計算處理诵叁,最后再按照不同的計算類型對分批處理結(jié)果進行恰當?shù)膮R總處理雁竞,比小文件數(shù)據(jù)的處理要很雜很多。大文件的種類也有多種拧额,例如文本文件碑诉、Excel文件、XML文件侥锦、JSON文件进栽、HTTP文件……等等,其中以文本 (txt 或 csv) 最為常見恭垦。

可以用于處理大文件的程序語言一般有以下幾種:

1快毛、 常規(guī)高級編程語言格嗅,比如 Java、C/C++唠帝、C#屯掖、Basic 等

2、? 將文件數(shù)據(jù)導入到數(shù)據(jù)庫后用SQL來處理

3襟衰、? Python

4懂扼、? esProc SPL

本文以文本文件舉例,依次介紹以上幾種程序方法進行大文件計算的特點右蒲。其它類型文件數(shù)據(jù)阀湿,除了讀入數(shù)據(jù)的方式不同,讀入后的處理思路就都與文本文件相似瑰妄。

文中要用到的訂單文件orders.txt中有5個列:orderkey陷嘴、orderdate、state间坐、quantity灾挨、amount,列數(shù)據(jù)間以TAB分隔竹宋,文件中第一行是列名劳澄,總共有1000萬行數(shù)據(jù)。如下:

一蜈七、??高級語言(以Java為例)

用高級語言編程來計算秒拔,計算過程怎么編寫,與具體的計算類型有關飒硅,不同類型的計算需要不同的計算過程砂缩。我們先來看看最簡單的合計運算,例如求訂單表orders.txt中訂單金額amount的總和三娩,用Java寫出來是這樣的:

BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream("orders.txt") ) );

String[] fieldNames = br.readLine().split("\t");

double sumAmount = 0;

String line = null;

while(( line = br.readLine() )!= null) {

String[] values = line.split("\t");

float amount = Float.parseFloat(values[4] );? //假定已知第 5 列是 amount

sumAmount += amount;

}

這段程序是一次讀一行數(shù)據(jù)庵芭,訪問文件時間太多,運行速度慢雀监。想要運行快一些双吆,需要一次讀入大塊數(shù)據(jù)(比如1萬行),然后再用代碼把數(shù)據(jù)拆成行來處理会前,過程會麻煩很多好乐。

這是最簡單的計算了,沒有數(shù)據(jù)過濾和分組回官、排序等要求曹宴。其它求平均值、最大值與最小值的計算歉提,跟這差不多笛坦。

如果要做分組匯總区转,代碼就會麻煩得多。比如按州state分組后求各州的訂單金額總和版扩,計算思路是這樣的:把各個分組保存起來废离,然后一行行地讀各行中的state值,與保存的組比較礁芦,找到了則將本行訂單金額加到組上蜻韭,沒找到則新加入一個組。最后直到所有行都處理完柿扣。如果按多個字段分組求多個統(tǒng)計值肖方,比如按日期和州分組求訂單金額總和、最大訂單金額未状,程序的復雜度就會增加很多俯画。

排序就更麻煩,還需要中間緩存文件司草。例如要按訂單金額從大到小排序艰垂,因內(nèi)存不足,不能讀入所有數(shù)據(jù)來排序埋虹,計算思路是這樣的:先讀入5000行(讀多少行合適要根據(jù)內(nèi)存而定)數(shù)據(jù)猜憎,排序后存到一個臨時文件,再讀入5000行排序后存到另一個臨時文件……直到所有數(shù)據(jù)處理完搔课,最后對這些臨時文件進行有序歸并——讀出每個臨時文件的第一行胰柑,找出應該排在最前面的那一行,寫入到結(jié)果文件辣辫,然后從那個臨時文件中再讀出一行旦事,繼續(xù)比較找出最前面的一行寫入結(jié)果文件。按此方法不斷進行急灭,直到所有數(shù)據(jù)行都寫入結(jié)果文件。

用高級語言完成大文件的處理確實是相當繁瑣的谷遂,對于非專業(yè)的程序人員葬馋,這幾乎是不可行的。

二肾扰、??利用數(shù)據(jù)庫

數(shù)據(jù)庫內(nèi)置了許多計算算法畴嘶,對數(shù)據(jù)的查詢計算功能比較完善,性能也比較好集晚,因此可以考慮將文件型數(shù)據(jù)導入到數(shù)據(jù)庫窗悯,生成數(shù)據(jù)庫表,再使用SQL來進行數(shù)據(jù)查詢計算偷拔。

這個辦法麻煩的地方就是要將文件數(shù)據(jù)導入數(shù)據(jù)庫蒋院,在導入數(shù)據(jù)之前亏钩,先要創(chuàng)建數(shù)據(jù)表結(jié)構(gòu),指定每個列的數(shù)據(jù)類型欺旧,例如創(chuàng)建訂單表的SQL如下:

CREATE TABLE orders ( orderkey INTEGER NOT NULL,

orderdate DATE NOT NULL,

state? CHAR(20) NOT NULL,

quantity? INTEGER NOT NULL,

amount? DECIMAL(15,2) NOT NULL,

PRIMARY KEY(orderkey)

);

如果換個其它結(jié)構(gòu)的數(shù)據(jù)文件姑丑,那么需要另寫一條建表的SQL。這里特別需要指定數(shù)據(jù)類型辞友,否則數(shù)據(jù)庫無法接受這些數(shù)據(jù)栅哀,而這是許多非專業(yè)程序員很不熟悉的地方。

對于導入過程称龙,數(shù)據(jù)庫一般都提供了直接導入文本文件的工具留拾,而其它文件則不能直接導入,需要先轉(zhuǎn)換為文本文件鲫尊。Excel文件還可以直接另存為文本间驮,而對于XML文件、JSON文件马昨、HTTP文件等則又需要編寫程序?qū)⑺鼈冝D(zhuǎn)化為文本文件竞帽,或者編寫程序先讀入文件數(shù)據(jù),生成一條SQL語句將數(shù)據(jù)寫入數(shù)據(jù)庫表中鸿捧,無論如何都是非常繁瑣的事情屹篓。

數(shù)據(jù)存入到數(shù)據(jù)庫表以后,查詢計算確實就非常簡單了匙奴,分組堆巧、排序都挺容易,示例如下:

1泼菌、? 求訂單金額總和

select sum(amount) from orders;

2谍肤、? 按州分組求各州訂單金額總和

select state, sum(amount) from orders group by state;

3、? 按訂單金額排序

select * from orders order by amount;

利用數(shù)據(jù)庫能很方便地查詢計算較大數(shù)據(jù)量哗伯,但把大文件導入數(shù)據(jù)庫卻很繁瑣而且有一定的專業(yè)技能要求荒揣。相對于高級語言的可行性大幅提高,但仍不夠好焊刹。

三系任、??Python

Python也沒有提供直接針對大文件的處理語法,其實現(xiàn)思路和高級語言類似虐块,如前面的計算訂單金額總和寫出來大概是:

sumAmount=0

with open("orders.txt",'r') as f:

while True:

line = f.readline()

if not line:

break

sumAmount += float(line.split("\t")[4])

print(sumAmount)

對于分組排序這類復雜一些的運算俩滥,如果實現(xiàn)前面說過的思路,用Python也非常麻煩贺奠,并不比java簡單多少霜旧。但Python有個pandas包,封裝了不少結(jié)構(gòu)化數(shù)據(jù)的處理函數(shù)儡率。如果是可讀入內(nèi)存的小文件挂据,它可以很簡單地處理以清。可惜的是棱貌,pandas沒有針對大文件提供直接分批處理的方法玖媚,還是要自己寫。使用pandas的復雜度比直接硬寫要小很多婚脱,但仍然要實現(xiàn)前面討論過的思路今魔。

分組運算寫起來太麻煩,我們還是把上面的求和運算基于pandas寫出來感受一下障贸。

import pandas as pd

chunk_data = pd.read_csv("orders.txt",sep="\t",header=None,chunksize=100000)

sumAmount=0

for chunk in chunk_data:

sumAmount+=chunk[4].sum()

print(sumAmount)

使用pandas后可以把文本看成一行行有結(jié)構(gòu)的數(shù)據(jù)错森,不再需要自己拆分。


Python處理小文件沒有大問題篮洁,但對于大文件未提供有效支持涩维。和高級語言相比,減輕的工作量很有限袁波,可用程度不高瓦阐,還不如數(shù)據(jù)庫。

另外篷牌,Python是個解釋執(zhí)行語言睡蟋,執(zhí)行速度遠遠低于高級語言,處理大文件時感受會更明顯枷颊。


四戳杀、??esProc ?SPL

esProc是專業(yè)的數(shù)據(jù)處理工具,與數(shù)據(jù)庫一樣內(nèi)置了各種查詢計算算法夭苗,可以直接使用文本信卡、Excel、Xml题造、Json等文件數(shù)據(jù)計算傍菇,不需要導入數(shù)據(jù)的過程。

esProc提供了游標晌梨,可以分批讀入數(shù)據(jù)再計算桥嗤,這樣就可以很方便地處理大文件了。象前面的例子仔蝌,只要寫一行代碼就可以:

1、? 求訂單金額總和

=file("orders.txt").cursor@t().total(sum(amount))

如果想再加個過濾也很容易荒吏,比如只統(tǒng)計2009年開始的訂單金額總和:

=file("orders.txt").cursor@t().select(orderdate>=date("2009-01-01")).total(sum(amount))

做分組敛惊、排序也簡單:

2、? 按州分組求各州訂單金額總和

=file("orders.txt").cursor@t().groups(state;sum(amount))

3绰更、? 按訂單金額排序

=file("orders.txt").cursor@t().sortx(amount)


esProc甚至還允許直接對文件使用SQL查詢瞧挤,如前面3例寫出來如下:

$select sum(amount) from "orders.txt"

$select state, sum(amount) from "orders.txt" group by state

$select * from "orders.txt" order by amount


esProc還內(nèi)置了并行計算锡宋,能充分利用多核CPU提高性能,這對于大文件是特別有用的特恬。比如分組匯總計算寫成:

=file("orders.txt").cursor@tm(;4).groups(state;sum(amount))

將會按 4 路并行方式計算执俩,在普通多核筆記本上速度能提高 2-3 倍。相對來講癌刽,高級語言能實現(xiàn)并行役首,但不僅麻煩,而且只有專業(yè)程序員才會做显拜。Python基本上不能并行衡奥。SQL得看數(shù)據(jù)庫,Oracle這種專業(yè)數(shù)據(jù)庫沒問題远荠,而簡易的MySQL就不行矮固。

esProc SPL擁有了SQL的優(yōu)點,又避免了數(shù)據(jù)導入的麻煩譬淳,對于桌面數(shù)據(jù)分析人員來講档址,是用于處理大文件的最合適工具。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邻梆,一起剝皮案震驚了整個濱河市守伸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌确虱,老刑警劉巖含友,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異校辩,居然都是意外死亡窘问,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門宜咒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惠赫,“玉大人,你說我怎么就攤上這事故黑《郏” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵场晶,是天一觀的道長混埠。 經(jīng)常有香客問我,道長诗轻,這世上最難降的妖魔是什么钳宪? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上吏颖,老公的妹妹穿的比我還像新娘搔体。我一直安慰自己,他們只是感情好半醉,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布疚俱。 她就那樣靜靜地躺著,像睡著了一般缩多。 火紅的嫁衣襯著肌膚如雪呆奕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天瞧壮,我揣著相機與錄音登馒,去河邊找鬼。 笑死咆槽,一個胖子當著我的面吹牛陈轿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秦忿,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼麦射,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了灯谣?” 一聲冷哼從身側(cè)響起潜秋,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胎许,沒想到半個月后峻呛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡辜窑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年钩述,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穆碎。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡摄悯,死狀恐怖橄仍,靈堂內(nèi)的尸體忽然破棺而出宛渐,到底是詐尸還是另有隱情屁奏,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布色徘,位于F島的核電站恭金,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏褂策。R本人自食惡果不足惜蔚叨,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一床蜘、第九天 我趴在偏房一處隱蔽的房頂上張望辙培。 院中可真熱鬧蔑水,春花似錦、人聲如沸扬蕊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尾抑。三九已至歇父,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間再愈,已是汗流浹背榜苫。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留翎冲,地道東北人垂睬。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像抗悍,于是被迫代替她去往敵國和親驹饺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 什么是大文件缴渊?大文件是指大到計算機內(nèi)存不足以一次性讀入的文件赏壹。這種情況,直接使用桌面數(shù)據(jù)工具(比如 Excel)都...
    心宇gxy閱讀 310評論 0 1
  • Python作為一門程序設計語言衔沼,在易讀蝌借、易維護方面有獨特優(yōu)勢,越來越多的人使用 Python 進行數(shù)據(jù)分析和處理...
    心宇gxy閱讀 992評論 0 1
  • Python作為一門程序設計語言指蚁,在易讀菩佑、易維護方面有獨特優(yōu)勢,越來越多的人使用 Python 進行數(shù)據(jù)分析和處理...
    西柚學報表閱讀 418評論 0 0
  • 本文分析大文件計算的實現(xiàn)原理欣舵,如過濾擎鸠、聚合計算、添加計算列缘圈、排序劣光、分組聚合、topN 等糟把,以及利用并行計算來提高計...
    小黃鴨呀閱讀 520評論 0 0
  • 在數(shù)據(jù)處理業(yè)務中绢涡,經(jīng)常要把文件結(jié)構(gòu)相同或近似相同的數(shù)據(jù)文件合并成一個文件,或者將一個比較大的數(shù)據(jù)文件拆分成小的數(shù)據(jù)...
    心宇gxy閱讀 456評論 0 1