refer : https://yq.aliyun.com/articles/530060?spm=a2c4e.11153940.blogcont181452.16.413f2ef21NKngz#python
http://www.datayuan.cn/article/6737.htm程序員
-
數組
大文本數據的讀寫
有時候咱們會拿到一些很大的文本文件,完整讀入內存,讀入的過程會很慢,甚至可能沒法讀入內存,或者能夠讀入內存,可是無法進行進一步的計算,這個時候若是咱們不是要進行很複雜的運算,可使用read_csv提供的chunksize或者iterator參數,來部分讀入文件,處理完以後再經過to_csv的mode='a',將每部分結果逐步寫入文件。數據結構
to_csv, to_excel的選擇
在輸出結果時統稱會遇到輸出格式的選擇,平時你們用的最多的.csv, .xls, .xlsx,後二者一個是excel2003,一個是excel2007,個人經驗是csv>xls>xlsx,大文件輸出csv比輸出excel要快的多,xls只支持60000+條記錄,xlsx雖然支持記錄變多了,可是,若是內容有中文經常會出現詭異的內容丟失。所以,若是數量較小能夠選擇xls,而數量較大則建議輸出到csv,xlsx仍是有數量限制,並且 大數據 量的話,會讓你以爲python都死掉了app
讀入時處理日期列
我以前都是在數據讀入後經過to_datetime函數再去處理日期列,若是數據量較大這又是一個浪費時間的過程,其實在讀入數據時,能夠經過parse_dates參數來直接指定解析爲日期的列。它有幾種參數,TRUE的時候會將index解析爲日期格式,將列名做爲list傳入則將每個列都解析爲日期格式ide
關於to_datetime函數再多說幾句,咱們拿到的時期格式經常出現一些亂七八糟的怪數據,遇到這些數據to_datimetime函數默認會報錯,其實,這些數據是能夠忽略的,只須要在函數中將errors參數設置爲'ignore'就能夠了。函數
另外,to_datetime就像函數名字顯示的,返回的是一個時間戳,有時咱們只須要日期部分,咱們能夠在日期列上作這個修改,datetime_col = datetime_col.apply(lambda x: x.date()),用map函數也是同樣的datetime_col = datetime_col.map(lambda x: x.date())工具
把一些數值編碼轉化爲文字
前面提到了map方法,我就又想到了一個小技巧,咱們拿到的一些數據每每是經過數字編碼的,好比咱們有gender這一列,其中0表明男,1表明女。固然咱們能夠用索引的方式來完成性能
其實咱們有更簡單的方法,對要修改的列傳入一個dict,就會達到一樣的效果。大數據
經過shift函數求用戶的相鄰兩次登陸記錄的時間差
以前有個項目須要計算用戶相鄰兩次登陸記錄的時間差,咋看起來其實這個需求很簡單,可是數據量大起來的話,就不是一個簡單的任務,拆解開來作的話,須要兩個步驟,第一步將登陸數據按照用戶分組,再計算每一個用戶兩次登陸之間的時間間隔。數據的格式很單純,以下所示
若是數據量不大的,能夠先unique uid,再每次計算一個用戶的兩次登陸間隔,相似這樣
這種方法雖然計算邏輯比較清晰易懂,可是缺點也很是明顯,計算量巨大,至關與有多少許記錄就要計算多少次。
那麼爲何說pandas的shift函數適合這個計算呢?來看一下shift函數的做用
恰好把值向下錯位了一位,是否是剛好是咱們須要的。讓咱們用shift函數來改造一下上面的代碼。
上面的代碼就把pandas向量化計算的優點發揮出來了,規避掉了計算過程當中最耗費時間的按uid循環。若是咱們的uid都是一個只要排序後用shift(1)就能夠取到全部前一次登陸的時間,不過真實的登陸數據中有不少的不用的uid,所以再將uid也shift一下命名爲uid0,保留uid和uid0匹配的記錄就能夠了。
【方向】 2018-03-12 11:11:49 瀏覽2650 評論0
python
大數據
摘要: 本文是針對Python設計一種並行處理數據的解決方案——使用Dask和Numba並行化加速運算速度。案例對比分析了幾種不一樣方法的運算速度,很是直觀,可供參考。
若是你善於使用Pandas變換數據、建立特徵以及清洗數據等,那麼你就可以輕鬆地使用Dask和Numba並行加速你的工做。單純從速度上比較,Dask完勝Python,而Numba戰勝Dask,那麼Numba+Dask基本上算是無敵的存在。將數值計算分紅Numba sub-function和使用Dask map_partition+apply,而不是使用Pandas。對於100萬行數據,使用Pandas方法和混合數值計算建立新特徵的速度比使用Numba+Dask方法的速度要慢許多倍。
Python:60.9x | Dask:8.4x | Numba:5.8x |Numba+Dask:1x
8be99f10ed908533e525b81fcd04bcdf3b27db2d
做爲舊金山大學的一名數據科學碩士,會常常跟數據打交道。使用Apply函數是我用來建立新特徵或清理數據的衆多技巧之一。如今,我只是一名數據科學家,而不是計算機科學方面的專家,但我是一個喜歡搗鼓並使得代碼運行更快的程序員。如今,我將會分享我在並行應用上的經驗。
大多Python愛好者可能瞭解Python實現的全局解釋器鎖(GIL),GIL會佔用計算機中全部的CPU性能。更糟糕的是,咱們主要的數據處理包,好比Pandas,不多能實現並行處理代碼。
Apply函數vs Multiprocessing.map
Tidyverse已經爲處理數據作了一些美好的事情,Plyr是我最喜好的數據包之一,它容許R語言使用者輕鬆地並行化他們的數據應用。Hadley Wickham說過:
「plyr是一套處理一組問題的工具:須要把一個大的數據結構分解成一些均勻的數據塊,以後對每一數據塊應用一個函數,最後將全部結果組合在一塊兒。」
對於Python而言,我但願有相似於plyr這樣的數據包可供使用。然而,目前這樣的數據包還不存在,但我可使用並行數據包構成一個簡單的解決方案。
Dask
bbcc3ca9a96dc7ad7129d9047a2d58be57a4ed84
以前在Spark上花費了一些時間,所以當我開始使用Dask時,仍是比較容易地掌握其重點內容。Dask被設計成可以在多核CPU上並行處理任務,此外也借鑑了許多Pandas的語法規則。
如今開始本文所舉例子。對於最近的數據挑戰而言,我試圖獲取一個外部數據源(包含許多地理編碼點),並將其與要分析的一大堆街區相匹配。在計算歐幾里得距離的同時,使用最大啓發式將最大值分配給一個街區。
8809febd555c55a69522a58770971c8cf0c57af5
最初的apply:
Dask apply:
兩者看起來很類似,apply核心語句是map_partitions,最後有一個compute()語句。此外,不得不對npartitions初始化。 分區的工做原理就是將Pandas數據幀劃分紅塊,對於個人電腦而言,配置是6核-12線程,我只需告訴它使用的是12分區,Dask就會完成剩下的工做。
接下來,將map_partitions的lambda函數應用於每一個分區。因爲許多數據處理代碼都是獨立地運行,因此沒必要過多地擔憂這些操做的順序問題。最後,compute()函數告訴Dask來處理剩餘的事情,並把最終計算結果反饋給我。在這裏,compute()調用Dask將apply適用於每一個分區,並使其並行處理。
因爲我經過迭代行來生成一個新隊列(特徵),而Dask apply只在列上起做用,所以我沒有使用Dask apply,如下是Dask程序:
Numba、Numpy和Broadcasting
因爲我是根據一些簡單的線性運算(基本上是勾股定理)對數據進行分類,因此認爲使用相似下面的Python代碼會運行得更快一些。
d31908d0ecfefd263b3e5373461b34374de9adf5
Broadcasting用以描述Numpy中對兩個形狀不一樣的矩陣進行數學計算的處理機制。假設我有一個數組,我會經過迭代並逐個變換每一個單元格來改變它
相反,我徹底能夠跳過for循環,並對整個數組執行操做。Numpy與broadcasting混合使用,用來執行元素智能乘積(對位相乘)。
Broadcasting能夠實現更多的功能,如今看看骨架代碼:
從本質上講,代碼的功能是改變數組。好的一方面是運行很快,甚至能和Dask並行處理速度比較。其次,若是使用的是最基本的Numpy和Python,那麼就能夠及時編譯任何函數。壞的一面在於它只適合Numpy和簡單Python語法。我不得不把全部的數值計算從個人函數轉換成子函數,但其計算速度會增長得很是快。
將其一塊兒使用
簡單地使用map_partition()就能夠將Numba函數與Dask結合在一塊兒,若是並行操做和broadcasting可以密切合做以加快運行速度,那麼對於大數據集而言,將會看到其運行速度獲得大幅提高。
09e60c6e34586f4760449a2159928877d49958cf
d9d0d60dc749ba864cbb200bb05b60e71ff6adcf
上面的第一張圖代表,沒有broadcasting的線性計算其表現不佳,並行處理和Dask對速度提高也有效果。此外,能夠明顯地發現,Dask和Numba組合的性能優於其它方法。
上面的第二張圖稍微有些複雜,其橫座標是對行數取對數。從第二張圖能夠發現,對於1k到10k這樣小的數據集,單獨使用Numba的性能要比聯合使用Numba+Dask的性能更好,儘管在大數據集上Numba+Dask的性能很是好。
優化
爲了可以使用Numba編譯JIT,我重寫了函數以更好地利用broadcasting。以後,從新運行這些函數後發現,平均而言,對於相同的代碼,JIT的執行速度大約快了24%。
c9f6a34759b5b1298033c2e4ffd5d78a63994af5
能夠確定的說,必定有進一步的優化方法使得執行速度更快,但目前沒有發現。Dask是一個很是友好的工具,本文使用Dask+Numba實現的最好成果是提高運行速度60倍。