0x08 大数据分析,七层基本功
摘要:欲練數據神功,必先揮刀……,嗯,先扎好馬步吧!編寫SQL語句,是數據統計分析最基本的能力了。覺得SQL的自定義功能太弱了,或者你覺得就算是Hive調用外部腳本也麻煩了,那么我們上當前最熱的Spark
00 引言
2016就要來了,避不及,躲不開。新一年來之前,還是有一件值得高興的事情,那便是年終獎了。
公司大了,什么樣的人都有。嗯嗯……,說錯了,是人大了,什么樣的公司都進。嗯嗯……,還是不對。是公司大了,員工多了,要統計每個員工每年寫的代碼數量。以此來分配年終獎了。
假設有如下數據示例,第一列為員工的ID,第二列為年份,第三列為代碼數。
126882,2005,5
126882,2013,16
127305,2010,2
127305,2014,29
128194,2012,1
128194,2013,161
欲練數據神功,必先揮刀……,嗯,先扎好馬步吧。下面的7個步驟,是練好數據基本功的一些方法。
01 MySQL版本
編寫SQL語句,是數據統計分析最基本的能力了。一般統計分析中,掌握好join語句分析即可,其它數據庫相關的備份、恢復、存儲過程之類的,基本上很少用到。
用一個join來實現需求,取出數據:
select a.* from table as a join table as b on a.id=b.id where a.count>b.count;本例中是自己和自己join,最簡單的inner join,將兩個表中按id相同的行進行關聯起來,最后按條件進行篩選需要的數據即可。需要注意,MySQL中的臨時表,是沒有辦法自己join自己的。
02 Bash版本
我們通常會以SQL為常用工具,如果SQL不能滿足你的需求,或者實現起來比較麻煩,你可以導出成csv格式的文本文件。
Shell命令比通常想像的要強大,用好Shell命令,很多時候也可以方便的處理問題。
join -t',' -1 1 -2 1 data.csv data.csv | awk -F',' '$3>$5{print $1,$4,$5}'這條命令看起來估計算最簡潔了的,但還是用了兩個命令。join也是一個非常神奇的命令,可以完成關系數據庫的join功能,包括left join,right join,outer join,inner join。
本例中指定了連接的字段,參數“-1 1 -2 1”分別指定第一個、第二個文件的第1個字段作為關聯字段。將連接的數據使用awk進行簡單的過濾處理。join命令相當于SQL中的join的功能,而附帶的awk相當于SQL中的where條件,進行數據篩選。
03 Awk版本
在shell命令行下,還有一個強大的數據處理工具:AWK,強大到能獨立完成很多數據處理和分析的任務,后面會有單獨的篇章來介紹,請持續關注。
上面一段簡單的Awk代碼,把Awk的一些基本概念都用上了。也算是“麻雀雖小,五臟俱全”了。涉及Awk的三段式代碼結構,數組與賦值,條件判斷與循環等編程基礎概念。
因為awk是按行讀入文件,因此我們的思想就是將當前的最大的值存儲起來,再讀入下一行,如果比當前最大值大,就更新,否則繼續讀入一行。
處理文件文件的方式,自然與數據庫的join思想不一樣,但你需要習慣這種方式,因為這種處理文件文件的方式,也是很多NoSQL的處理方式。
04 Python版本
前面幾篇文章都安利了Python,處理這種簡單的統計,我們也可以用Python來試試。
處理的方式還是一樣,按行讀取文件并存儲和記錄,但邏輯實現起來感覺稍微有點繞而已。沒有用數組或字典之類的來存儲數據。
還需要注意,這個程序是需要對文件進行按id排序的,因為代碼處理的是連續的行,并且假定相同的id是在連續的行上。
當然,你肯定會說,這個代碼寫得有些雜亂,不符合通常的思路。之所以寫成這樣,是因為我們后面在分布式環境中還要用。
05 Hive版本
也許你會想,如果文件很大,很大,很大(重要的說三遍嗎?),那么如何處理呢?馬上就2016了,那么你聽過安利嗎?哦不對,是大數據,一個已經被說到爛透了的詞。單機不能滿足你的需求,那么使用分布式。
假設Facebook有20億用戶,統計每個用戶在每天中,各自發的消息的最多的那天和發送的條數,假設所有用戶,每天都發消息。20億用戶,按Facebook上線10年算,3600天,共72000億條記錄,夠大了吧!分別找出每個用戶發消息最多的那天和發消息的次數。
且來看看,由Facebook開源出來的Hive數據倉庫,如何處理!
-- 見MySQL版本你沒有看錯,我也沒有騙你,還真是和MySQL用同樣的代碼。當然,Hive有自己的優化之類的,暫時先不管。
這個地方,有個前提,你只需要把那72000億條數據,存放到HDFS文件系統上,然后建立一個外部表和HDFS文件進行關聯,然后輸入和MySQL同樣的語句,Hive引擎會自然將SQL語句轉換為下層的map-reduce代碼運行。
重要的是,你的Hadoop集群有多強大,這個Hive語句就能達到多強大。還不用自己寫map-reduce程序,就是分析師最熟悉的SQL語句。
如果你覺得Hive也是SQL語句,有些自定義的函數或者方法比較麻煩,那么Hive還可以調用外部的腳本,只要是可執行腳本都行:python、ruby、bash、scala、java、lisp隨便你愛好。
06 Spark版本
如果你覺得用Hive太Low了,跟不上時代的步伐了。或者,你覺得SQL的自定義功能太弱了,或者你覺得就算是調用外部腳本也很麻煩,那么我們上當前最熱的Spark。
Spark支持幾種編程接口,Scala、Java、Python,最近也開始支持R了。
上面雖然連續用了好幾個map,但原理卻非常簡單,和python的map功能類似。唯一用了一個groupByKey功能,將相同的id聚合在一起,剩下的屬性放在一個列表里面。對這個列表進行排序,取count最多的次數和年份,最后輸出。
邏輯夠簡單,代碼也夠簡潔。Spark強大的便利利益于Scala強大的數據結構與數據處理能力。
07 map-reduce版本
如果你追求完全的原生,或者追求完全的可控性。但又不熟悉Java代碼,那么還是可以用Python來寫map-reduce程序。
又一個大騙子!
通過Hadoop的Streaming接口來進行調用,只需要自定義mapper和reducer程序即可。上面的mapper和reducer可以直接用純粹Python的單機版本。
輸入是一些id,year,count行,輸出還是同樣的數據結構。只是在程序中,把當前這個程序的輸入中,每個id最多的count和year找出來了。數據量已經減少了,每個id只會保留最大的一條數據。
分布式最基本的原理就是數據分塊,在map階段,對每個塊的數據調用mapper程序,求出當前塊里面每個id的最大count和year找出來。把這些輸出作為reducer的輸入,再求一次最大值,那么找出的便是全局的最大值。
08 結尾
數據分析基本功,按上面七個方面,扎好了馬步,離數據神功第一層也不遠了。
不要興奮,也許會突然冒出來一個小姑娘,告訴你說:切,上面的功能我用Excel也可以完美的實現。
當然可以了,聰明如你,Excel還能實現比這強大得多的功能。
理論上來說,上面所有工具都能完成任何統計分析需求。只是不同的地方,實現的方式各有不同,有的復雜,有的簡單,有的快,有的慢而已。選擇你覺得最簡單的方式,搞定任務即可。
總結
以上是生活随笔為你收集整理的0x08 大数据分析,七层基本功的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【mysql】使用tpcc-mysql进
- 下一篇: UITableView优化