統(tǒng)計和數(shù)據(jù)處理都離不開csv文件窒舟,一般來說系忙,操作csv都是依賴第三方軟件,如Excel惠豺、Matlab這樣的银还;也可以自己編程,用Python耕腾、Perl等等见剩,直接操作文件比較麻煩杀糯。
但對簡單的處理扫俺,用大體量的軟件或是寫一段代碼有點殺雞用牛刀的感覺,這時固翰,csvkit就有用武之地狼纬。
開始
安裝csvkit
安裝csvkit很簡單:
pip3 install csvkit
我的系統(tǒng)是Python3.6,所以用pip3來安裝骂际,如果還在用Python2.7疗琉,就用pip install csvkit
來進行安裝。
為了方便后面的測試和解釋歉铝,建議從官方下載測試樣本文件:
curl -L -O https://raw.githubusercontent.com/wireservice/csvkit/master/examples/realdata/ne_1033_data.xlsx
in2csv:Excel的殺手
下載的樣本文件是一個Excel文件盈简,誰愿意為了僅僅看兩行數(shù)據(jù)而等待Excel漫長的啟動界面呢?所以首先要將它轉(zhuǎn)換為csv文件,轉(zhuǎn)換也不用打開Excel柠贤,一條命令:
in2csv ne_1033_data.xlsx > data.csv
>
是shell的重定向符香浩,如果不重定向,in2csv會將轉(zhuǎn)換之后的內(nèi)容輸出到控制臺顯示臼勉,現(xiàn)在我希望能保存為csv文件便于后續(xù)的操作邻吭,所以就將內(nèi)容輸出定向到data.csv文件中。
接下來看看data.csv的內(nèi)容吧:
cat data.csv
csv文件內(nèi)容有了宴霸,如果用cat
的方式來看囱晴,既不方便也不美觀,接下來我們用另一個工具查看
csvlook:數(shù)據(jù)潛望鏡
這個文件有多少行呢瓢谢,用cat data.csv | wc -l
看了一下畸写,有1037行,所以一屏肯定是看不完的氓扛,需要分頁查看艺糜,而分頁功能在類Unix系統(tǒng)上有現(xiàn)成的less
可用。
csvlook data.csv | less -S
這樣的顯示就好多了幢尚,還可以方向鍵滾動查看破停,q
退出,/
搜索尉剩,等一系列less
專用操作真慢。
csvcut:數(shù)據(jù)手術(shù)刀
既然名字中帶了一個cut
,聰明的你肯定猜到了它的用途理茎,不過放心黑界,所有的操作都不會修改輸入(原始文件),只會影響輸出皂林。
先看看這個數(shù)據(jù)有哪些列
csvcut -n data.csv
可以看到朗鸠,總共有14列,在輸出信息中础倍,前面的數(shù)字是數(shù)字索引位置烛占,默認是從1開始計數(shù),后面的是列名稱沟启,我想只看感興趣的幾列數(shù)據(jù)(在這里我為了演示忆家,只顯示4行數(shù)據(jù),所以加了head
進行輸出行數(shù)限定):
csvcut -c 2,5,6 data.csv | head -n 5
可以看到既可以用數(shù)字作為索引德迹,也可以用列名稱作為索引芽卿,所以上面的指令和下面這個指令是等價的
csvcut -c county,item_name,quantity data.csv | head -n 5
用管道進行組合
上面的輸出不錯,能否再顯示得美觀一點呢胳搞?答案是肯定的卸例,將命令用管道組合起來就行了
csvcut -c county,item_name,quantity data.csv | csvlook | head
|
管道是類Unix平臺上的強大能力称杨,如果不關(guān)心中間結(jié)果,甚至可以從頭到尾都用管道進行連接筷转,例如上面的命令改成如下方式列另,也是一樣的結(jié)果
in2csv ne_1033_data.xlsx | csvcut -c county,item_name,quantity | csvlook | head
這樣就省去了生成data.csv文件的中間過程。
數(shù)據(jù)分析
csvstat:無代碼亦統(tǒng)計
使用csvlook
和csvcut
查看數(shù)據(jù)的切片只是探索數(shù)據(jù)的開始旦装,在實踐中页衙,通常還需要一些計算和統(tǒng)計,csvstat
的設(shè)計靈感來自編程語言 “R”的summary()
統(tǒng)計阴绢,它可以統(tǒng)計匯總一個CSV文件中的數(shù)據(jù)列店乐。
csvcut -c county,acquisition_cost,ship_date data.csv | csvstat
不知道你有沒有統(tǒng)計學(xué)基礎(chǔ)?如果有的話呻袭,應(yīng)該一目了然眨八,唯一值、最小值左电、最大值廉侧、總計、均值篓足、中位值段誊、標準差……,大部分情況下夠用了:)
csvgrep:找到需要的數(shù)據(jù)
僅僅按照列的方式過濾還是比較弱栈拖,還需要按照內(nèi)容進行過濾连舍,這時csvgrep
就派上用場,例如涩哟,我們只想看蘭開斯特的數(shù)據(jù)索赏。
csvcut -c county,item_name,total_cost data.csv | csvgrep -c county -m LANCASTER | csvlook
csvgrep
還支持正則表達式,關(guān)于正則表達式的討論有點超出本篇范圍贴彼,有興趣可以查看系統(tǒng)工具grep
的手冊潜腻。
csvsort:秩序
前面顯示出來的內(nèi)容都很少,實際中往往都有成千上萬行器仗,所以排序功能很重要融涣,我們試一下用csvsort
對total_cost
列進行遞減順序:
csvcut -c county,item_name,total_cost data.csv | csvgrep -c county -m LANCASTER | csvsort -c total_cost -r | csvlook
寶刀屠龍
csvjoin:關(guān)聯(lián)數(shù)據(jù)
在上面的數(shù)據(jù)中,有各個地區(qū)的武器裝備信息青灼,接下來想了解一個問題——裝備有武器的地區(qū)中暴心,哪里的人口最少?
原來的數(shù)據(jù)表不包含人口數(shù)量杂拨,所以下載一個包含人口信息的數(shù)據(jù):
curl -L -O https://raw.githubusercontent.com/wireservice/csvkit/master/examples/realdata/acs2012_5yr_population.csv
兩個數(shù)據(jù)表都包含fips
字段,我們可以用這個字段來連接兩個數(shù)據(jù):
csvjoin -c fips data.csv acs2012_5yr_population.csv > joined.csv
csvcut -c county,item_name,total_population joined.csv | csvsort -c total_population | csvlook | head
csvstack:合并數(shù)據(jù)
數(shù)據(jù)經(jīng)常會分散在不同地方悯衬,這時希望將一堆的csv文件合并成一個數(shù)據(jù)文件弹沽,csvstack
可以幫助達成這個目標檀夹,一般來說csvstack
需要同列同名的數(shù)據(jù)才可以合并。但是你知道策橘,有時候即使兩個csv文件有稍微的不同炸渡,也可以通過csvcut
的列選擇來獲得同列同名的數(shù)據(jù)表。
# 獲得堪薩斯州的測試數(shù)據(jù)
curl -L -O https://raw.githubusercontent.com/wireservice/csvkit/master/examples/realdata/ks_1033_data.csv
# 使用相同的文件名命名規(guī)則
in2csv ne_1033_data.xlsx > ne_1033_data.csv
# 合并兩個文件到region.csv中
csvstack ne_1033_data.csv ks_1033_data.csv > region.csv
# 查看部分列的統(tǒng)計信息
csvstat -c state,acquisition_cost region.csv
csvsql, sql2csv:必殺技
有時丽已,僅僅命令行是不夠的蚌堵,需要用SQL來進行數(shù)據(jù)的操作,csvsql
和sql2csv
就提供了數(shù)據(jù)庫和csv之間的橋梁沛婴。
例如吼畏,我想將現(xiàn)在的csv文件轉(zhuǎn)為數(shù)據(jù)庫表
csvsql -i sqlite joined.csv
當然,我們可以一步到位嘁灯,直接創(chuàng)建一個本地數(shù)據(jù)庫:
csvsql --db sqlite:///leso.db --insert joined.csv
接下來泻蚊,就可以利用數(shù)據(jù)庫軟件對這個數(shù)據(jù)庫進行常規(guī)的SQL查詢,當然也可以用CSVKIT提供的小工具sql2csv
來進行查詢丑婿。
sql2csv --db sqlite:///leso.db --query "select * from joined where total_population<1000;" | csvcut -c state,county,total_population | csvlook
如果SQL查詢使用不頻繁性雄,何不直接在csv上執(zhí)行SQL查詢呢?
csvsql --query "select county,item_name,quantity from joined where quantity == 5;" joined.csv 2>/dev/null | csvlook
總結(jié)
由于我經(jīng)常做數(shù)據(jù)處理的計算羹奉,所以磁盤上總是有大量的csv文件秒旋,用普通的文本編輯器打開非常緩慢不說,還不方便查詢和檢視诀拭,有了這套工具確實方便了很多滩褥。此外,它對中文的處理也還行炫加,文件設(shè)置為UTF-8編碼就好瑰煎。