亿条数据读取工具_仅需1秒!搞定100万行数据:超强Python数据分析利器
作者:Maarten、Roman、Jovan
編譯:1+1=6
1、前言
使用Python進行大數據分析變得越來越流行。這一切都要從NumPy開始,它也是今天我們在推文介紹工具背后支持的模塊之一。
2、Vaex
Vaex是一種更快、更安全、總體上更方便的方法,可以使用幾乎任意大小的數據進行數據研究分析,只要它能夠適用于筆記本電腦、臺式機或服務器的硬盤驅動器。
https://vaex.readthedocs.io/en/latest/
Vaex是一個開源的DataFrame庫,它可以對表格數據集進行可視化、探索、分析,甚至機器學習,這些數據集和你的硬盤驅動器一樣大。它可以在一個n維網格上每秒計算超過10億(10^9)個對象的平均值、和、計數、標準差等統計信息。可視化使用直方圖、使用直方圖、密度圖和3D立體渲染進行可視化。為此,Vaex采用了內存映射、高效的外核算法和延遲計算等概念來獲得最佳性能(不浪費內存)。所有這些都封裝在一個類似Pandas的API中。
GitHub:https://github.com/vaexio/vaex
3、Vaex vs Dask、Pandas、Spark
Vaex與Dask不同,但與Dask DataFrames相似,后者是在Pandas DataFrame之上構建的。這意味著Dask繼承了Pandas issues,比如數據必須完全裝載到RAM中才能處理的要求,但Vaex并非如此。
Vaex不生成DataFrame副本,所以它可以在內存較少的機器上處理更大的DataFrame。
Vaex和Dask都使用延遲處理。唯一的區別是,Vaex在需要的時候才計算字段,而Dask需要顯式地使用compute函數。
數據需要采用HDF5或Apache Arrow格式才能充分利用Vaex。
1億行的數據集,對Pandas和Vaex執行相同的操作:
Vaex在我們的四核筆記本電腦上的運行速度可提高約190倍,在AWS h1.x8大型機器上,甚至可以提高1000倍!最慢的操作是正則表達式。正則表達式是CPU密集型的,這意味著大部分時間花在操作上,而不是花在它們周圍的所有bookkeeping上。
Apache Spark是JVM/Java生態系統中的一個庫,用于處理用于數據科學的大型數據集。如果Pandas不能處理特定的數據集,人們通常求助于PySpark。如果你的工作是生成結果,而不是在本地甚至在集群中設置Spark,那么這是一個額外的障礙。因此我們也對Spark進行了同樣的基準操作:
Spark的性能比Pandas更好,這是由于多線程的緣故。但vaex比Spark做得好得多。Spark以每秒1000萬串的速度運行(并且會隨著內核和機器的數量增加)。Vaex每秒可以處理1億條字符串,并且會隨著內核數量的增加而增加。在32核的機器上,我們每秒鐘處理10億個字符串。
4、Vaex真的很快!
流程都一樣:
pip install vaex讓我們創建一個DataFrame,它有100萬行和1000列:
import vaex import pandas as pd import numpy as np n_rows = 1000000 n_cols = 1000 df = pd.DataFrame(np.random.randint(0, 100, size=(n_rows, n_cols)), columns=['col%d' % i for i in range(n_cols)]) df.head()這個DataFrame占用了多少內存呢?
df.info(memory_usage='deep')把它保存到磁盤,這樣我們以后可以用Vaex讀取它:
file_path = 'big_file.csv' df.to_csv(file_path, index=False)直接通過Vaex或直接讀取CSV,這速度將類似于Pandas。在我們的電腦上,兩者都需要大約85秒。
我們需要將CSV轉換為HDF5,才能看到Vaex的優點。
事實上,Vaex只受可用磁盤空間的限制。如果你的數據不是內存映射文件格式(例如CSV、JSON),則可以通過與Vaex結合Pandas I/O輕松地轉換它。
我們可以將它轉換為HDF5并用Vaex處理它!
dv = vaex.from_csv(file_path, convert=True, chunk_size=5_000_000)上面的函數將自動創建一個HDF5文件并將其保存到硬盤。
檢查一下dv類型:
type(dv) # output vaex.hdf5.dataset.Hdf5MemoryMapped現在,讓我們用Vaex處理7.5GB的數據集——我們不需要讀取它,因為我們在上面的dv變量中已經有了它。這里只是為了測試速度。
dv = vaex.open('big_file.csv.hdf5')Vaex需要不到1秒的時間來執行上面的命令。但Vaex實際上并沒有讀取文件,因為延遲加載。
讓我們通過計算col1的和來讀取它。
suma = dv.col1.sum() suma # array(49486599)Vaex用不到1秒的時間計算好了結果。這是使用了內存映射。
5、虛擬列
Vaex在添加新列時創建一個虛擬列,虛列的行為與普通列一樣,但是它們不占用內存。這是因為Vaex只記得定義它們的表達式,而不預先計算值。這些列僅在必要時才被延遲計算,從而保持較低的內存使用率。
dv['col1_plus_col2'] = dv.col1 + dv.col2 dv['col1_plus_col2']Vaex在過濾數據時不會創建DataFrame副本,這是因為它屬于一個淺拷貝(Shallow Copy)。在創建過濾后的數據流時,Vaex會創建一個二進制掩碼,然后將其應用于原始數據,而不需要進行復制。這類過濾器的內存成本很低:
過濾10億行數據流需要大約1.2 GB的RAM。
與其他“經典”工具相比,這是可以忽略不計的,只需要100GB就可以讀取數據,而對于過濾后的dataframe,則需要另一個100GB。
dvv = dv[dv.col1 > 90]6、高性能聚合數據
列如value_counts、groupby、unique和各種字符串操作都使用了快速高效的算法,這些算法都是在C++底層實現的。它們都以非核心方式工作,這意味著你可以處理比RAM更大的數據,并使用處理器的所有可用內核。例如,對超過10億行執行value_counts操作只需1秒!
有了Vaex,你可以通過一個操作來完成,并且只需要一次數據傳遞!下面的group-by示例超過11億行,只需要30秒。
df.groupby(by='vendor_id', agg={'count': vaex.agg.count(),'count_fare_n_pass_lt3': vaex.agg.count(selection='passenger_count<3'),'count_fare_n_pass_ge3': vaex.agg.count(selection='passenger_count>=3'),'mean_fare_n_pass_lt3': vaex.agg.mean('fare_amount', selection='passenger_count<3'),'mean_fare_n_pass_ge3': vaex.agg.mean('fare_amount', selection='passenger_count>=3'),})7、即時編譯
只要虛擬列只使用Numpy或純Python操作定義,Vaex就可以通過jitting加速它的計算,或者通過Numba或Pythran進行即時編譯。如果你的機器有支持CUDA的NVIDIA顯卡,Vaex 也支持通過CUDA加速。這對于加速計算開銷很大的虛列的計算非常有用。
考慮下面的例子。我們已經定義了兩個地理位置之間的弧距離,這個計算涉及到相當多的代數和三角學知識。平均值計算將強制執行這個計算消耗相當大的虛列。當使用Numpy執行時,只需要30秒(11億行)。當我們對numba預編譯表達式執行同樣的操作時,我們的執行時間大約快了2.5倍,至少在我們的測試電腦上是這樣。如果有一個英偉達顯卡,可以嘗試一下!
def arc_distance(theta_1, phi_1, theta_2, phi_2):temp = (np.sin((theta_2-theta_1)/2*np.pi/180)**2+ np.cos(theta_1*np.pi/180)*np.cos(theta_2*np.pi/180) * np.sin((phi_2-phi_1)/2*np.pi/180)**2)distance = 2 * np.arctan2(np.sqrt(temp), np.sqrt(1-temp))return distance * 3958.8df['arc_distance_numpy'] = arc_distance(df.pickup_longitude, df.pickup_latitude, df.dropoff_longitude, df.dropoff_latitude)df['arc_distance_numba'] = arc_distance(df.pickup_longitude, df.pickup_latitude, df.dropoff_longitude, df.dropoff_latitude).jit_numba()mean_numpy = df.arc_distance_numpy.mean(progress='widget') mean_numba = df.arc_distance_numba.mean(progress='widget') print(f'Mean arc distance comuted with numpy: {mean_numpy:.5f}') print(f'Mean arc distance comuted with numba: {mean_numba:.5f}')8、Selections
Vaex實現了一個叫做Selections的概念用來選擇數據。例如:當你希望通過計算數據不同部分的統計數據而不是每次都創建一個新的引用DataFrame來分析數據時,這是非常有用的。使用選擇的真正強大之處在于:我們只需對數據進行一次傳遞,就可以計算出多次選擇的統計量。
select_n_passengers_lt3 = df.passenger_count < 3 select_n_passengers_ge3 = df.passenger_count >= 3df.fare_amount.mean(selection=[None, select_n_passengers_lt3, select_n_passengers_ge3], progress='widget')這對于制作各種可視化圖形也很有用。例如,我們可以使用.count方法在不同的選擇上創建兩個直方圖,只需對數據進行一次傳遞。非常有效!
binned_dist_npass_lt3, binned_dist_npass_ge3 = df.count(binby=['total_amount'],limits=[5, 50],shape=64,selection=[select_n_passengers_lt3, select_n_passengers_ge3], progress='widget')xvalues = np.linspace(5, 50, 64) plt.figure(figsize=(8, 4)) plt.plot(xvalues, binned_dist_npass_lt3, drawstyle="steps-pre", label='num passengers < 3', lw=3) plt.plot(xvalues, binned_dist_npass_ge3, drawstyle="steps-pre", label='num passengers >=3', lw=3) plt.legend(fontsize=14) plt.xlabel('Total amount [$]', fontsize=14) plt.ylabel('Number of trips', fontsize=14) plt.show()9、繪圖
Vaex將數據繪制成圖表的速度也很快。它具有特殊的繪圖函數plot1d、plot2d和plot2d_contour。
dv.plot1d(dv.col2, figsize=(14, 7))30倍!使用Cython加速Python代碼?mp.weixin.qq.comCuPy:將Numpy提速700倍!?mp.weixin.qq.com71803倍!超強Pandas循環提速攻略?mp.weixin.qq.com71803倍!超強Pandas循環提速攻略?mp.weixin.qq.com10個提高工作效率的Pandas小技巧,竟然可以這么用!?mp.weixin.qq.comCPU靠邊站!使用cuDF在GPU加速Pandas?mp.weixin.qq.com1000+倍!超強Python『向量化』數據處理提速攻略?mp.weixin.qq.comDatatable:Python數據分析提速高手,飛一般的感覺!?mp.weixin.qq.com量化投資與機器學習微信公眾號,是業內垂直于Quant、MFE、Fintech、AI、ML等領域的量化類主流自媒體。公眾號擁有來自公募、私募、券商、期貨、銀行、保險資管、海外等眾多圈內18W+關注者。每日發布行業前沿研究成果和最新量化資訊。
總結
以上是生活随笔為你收集整理的亿条数据读取工具_仅需1秒!搞定100万行数据:超强Python数据分析利器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果手机怎么设置时间24小时制_8款手机
- 下一篇: excel中vlookup函数的使用方法