亿条数据读取工具_仅需1秒!搞定100万行数据:超强Python数据分析利器
作者:Maarten、Roman、Jovan
編譯:1+1=6
1、前言
使用Python進(jìn)行大數(shù)據(jù)分析變得越來越流行。這一切都要從NumPy開始,它也是今天我們在推文介紹工具背后支持的模塊之一。
2、Vaex
Vaex是一種更快、更安全、總體上更方便的方法,可以使用幾乎任意大小的數(shù)據(jù)進(jìn)行數(shù)據(jù)研究分析,只要它能夠適用于筆記本電腦、臺式機(jī)或服務(wù)器的硬盤驅(qū)動器。
https://vaex.readthedocs.io/en/latest/
Vaex是一個開源的DataFrame庫,它可以對表格數(shù)據(jù)集進(jìn)行可視化、探索、分析,甚至機(jī)器學(xué)習(xí),這些數(shù)據(jù)集和你的硬盤驅(qū)動器一樣大。它可以在一個n維網(wǎng)格上每秒計算超過10億(10^9)個對象的平均值、和、計數(shù)、標(biāo)準(zhǔn)差等統(tǒng)計信息。可視化使用直方圖、使用直方圖、密度圖和3D立體渲染進(jìn)行可視化。為此,Vaex采用了內(nèi)存映射、高效的外核算法和延遲計算等概念來獲得最佳性能(不浪費(fèi)內(nèi)存)。所有這些都封裝在一個類似Pandas的API中。
GitHub:https://github.com/vaexio/vaex
3、Vaex vs Dask、Pandas、Spark
Vaex與Dask不同,但與Dask DataFrames相似,后者是在Pandas DataFrame之上構(gòu)建的。這意味著Dask繼承了Pandas issues,比如數(shù)據(jù)必須完全裝載到RAM中才能處理的要求,但Vaex并非如此。
Vaex不生成DataFrame副本,所以它可以在內(nèi)存較少的機(jī)器上處理更大的DataFrame。
Vaex和Dask都使用延遲處理。唯一的區(qū)別是,Vaex在需要的時候才計算字段,而Dask需要顯式地使用compute函數(shù)。
數(shù)據(jù)需要采用HDF5或Apache Arrow格式才能充分利用Vaex。
1億行的數(shù)據(jù)集,對Pandas和Vaex執(zhí)行相同的操作:
Vaex在我們的四核筆記本電腦上的運(yùn)行速度可提高約190倍,在AWS h1.x8大型機(jī)器上,甚至可以提高1000倍!最慢的操作是正則表達(dá)式。正則表達(dá)式是CPU密集型的,這意味著大部分時間花在操作上,而不是花在它們周圍的所有bookkeeping上。
Apache Spark是JVM/Java生態(tài)系統(tǒng)中的一個庫,用于處理用于數(shù)據(jù)科學(xué)的大型數(shù)據(jù)集。如果Pandas不能處理特定的數(shù)據(jù)集,人們通常求助于PySpark。如果你的工作是生成結(jié)果,而不是在本地甚至在集群中設(shè)置Spark,那么這是一個額外的障礙。因此我們也對Spark進(jìn)行了同樣的基準(zhǔn)操作:
Spark的性能比Pandas更好,這是由于多線程的緣故。但vaex比Spark做得好得多。Spark以每秒1000萬串的速度運(yùn)行(并且會隨著內(nèi)核和機(jī)器的數(shù)量增加)。Vaex每秒可以處理1億條字符串,并且會隨著內(nèi)核數(shù)量的增加而增加。在32核的機(jī)器上,我們每秒鐘處理10億個字符串。
4、Vaex真的很快!
流程都一樣:
pip install vaex讓我們創(chuàng)建一個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占用了多少內(nèi)存呢?
df.info(memory_usage='deep')把它保存到磁盤,這樣我們以后可以用Vaex讀取它:
file_path = 'big_file.csv' df.to_csv(file_path, index=False)直接通過Vaex或直接讀取CSV,這速度將類似于Pandas。在我們的電腦上,兩者都需要大約85秒。
我們需要將CSV轉(zhuǎn)換為HDF5,才能看到Vaex的優(yōu)點(diǎn)。
事實(shí)上,Vaex只受可用磁盤空間的限制。如果你的數(shù)據(jù)不是內(nèi)存映射文件格式(例如CSV、JSON),則可以通過與Vaex結(jié)合Pandas I/O輕松地轉(zhuǎn)換它。
我們可以將它轉(zhuǎn)換為HDF5并用Vaex處理它!
dv = vaex.from_csv(file_path, convert=True, chunk_size=5_000_000)上面的函數(shù)將自動創(chuàng)建一個HDF5文件并將其保存到硬盤。
檢查一下dv類型:
type(dv) # output vaex.hdf5.dataset.Hdf5MemoryMapped現(xiàn)在,讓我們用Vaex處理7.5GB的數(shù)據(jù)集——我們不需要讀取它,因?yàn)槲覀冊谏厦娴膁v變量中已經(jīng)有了它。這里只是為了測試速度。
dv = vaex.open('big_file.csv.hdf5')Vaex需要不到1秒的時間來執(zhí)行上面的命令。但Vaex實(shí)際上并沒有讀取文件,因?yàn)檠舆t加載。
讓我們通過計算col1的和來讀取它。
suma = dv.col1.sum() suma # array(49486599)Vaex用不到1秒的時間計算好了結(jié)果。這是使用了內(nèi)存映射。
5、虛擬列
Vaex在添加新列時創(chuàng)建一個虛擬列,虛列的行為與普通列一樣,但是它們不占用內(nèi)存。這是因?yàn)閂aex只記得定義它們的表達(dá)式,而不預(yù)先計算值。這些列僅在必要時才被延遲計算,從而保持較低的內(nèi)存使用率。
dv['col1_plus_col2'] = dv.col1 + dv.col2 dv['col1_plus_col2']Vaex在過濾數(shù)據(jù)時不會創(chuàng)建DataFrame副本,這是因?yàn)樗鼘儆谝粋€淺拷貝(Shallow Copy)。在創(chuàng)建過濾后的數(shù)據(jù)流時,Vaex會創(chuàng)建一個二進(jìn)制掩碼,然后將其應(yīng)用于原始數(shù)據(jù),而不需要進(jìn)行復(fù)制。這類過濾器的內(nèi)存成本很低:
過濾10億行數(shù)據(jù)流需要大約1.2 GB的RAM。
與其他“經(jīng)典”工具相比,這是可以忽略不計的,只需要100GB就可以讀取數(shù)據(jù),而對于過濾后的dataframe,則需要另一個100GB。
dvv = dv[dv.col1 > 90]6、高性能聚合數(shù)據(jù)
列如value_counts、groupby、unique和各種字符串操作都使用了快速高效的算法,這些算法都是在C++底層實(shí)現(xiàn)的。它們都以非核心方式工作,這意味著你可以處理比RAM更大的數(shù)據(jù),并使用處理器的所有可用內(nèi)核。例如,對超過10億行執(zhí)行value_counts操作只需1秒!
有了Vaex,你可以通過一個操作來完成,并且只需要一次數(shù)據(jù)傳遞!下面的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進(jìn)行即時編譯。如果你的機(jī)器有支持CUDA的NVIDIA顯卡,Vaex 也支持通過CUDA加速。這對于加速計算開銷很大的虛列的計算非常有用。
考慮下面的例子。我們已經(jīng)定義了兩個地理位置之間的弧距離,這個計算涉及到相當(dāng)多的代數(shù)和三角學(xué)知識。平均值計算將強(qiáng)制執(zhí)行這個計算消耗相當(dāng)大的虛列。當(dāng)使用Numpy執(zhí)行時,只需要30秒(11億行)。當(dāng)我們對numba預(yù)編譯表達(dá)式執(zhí)行同樣的操作時,我們的執(zhí)行時間大約快了2.5倍,至少在我們的測試電腦上是這樣。如果有一個英偉達(dá)顯卡,可以嘗試一下!
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實(shí)現(xiàn)了一個叫做Selections的概念用來選擇數(shù)據(jù)。例如:當(dāng)你希望通過計算數(shù)據(jù)不同部分的統(tǒng)計數(shù)據(jù)而不是每次都創(chuàng)建一個新的引用DataFrame來分析數(shù)據(jù)時,這是非常有用的。使用選擇的真正強(qiáng)大之處在于:我們只需對數(shù)據(jù)進(jìn)行一次傳遞,就可以計算出多次選擇的統(tǒng)計量。
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方法在不同的選擇上創(chuàng)建兩個直方圖,只需對數(shù)據(jù)進(jìn)行一次傳遞。非常有效!
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將數(shù)據(jù)繪制成圖表的速度也很快。它具有特殊的繪圖函數(shù)plot1d、plot2d和plot2d_contour。
dv.plot1d(dv.col2, figsize=(14, 7))30倍!使用Cython加速Python代碼?mp.weixin.qq.comCuPy:將Numpy提速700倍!?mp.weixin.qq.com71803倍!超強(qiáng)Pandas循環(huán)提速攻略?mp.weixin.qq.com71803倍!超強(qiáng)Pandas循環(huán)提速攻略?mp.weixin.qq.com10個提高工作效率的Pandas小技巧,竟然可以這么用!?mp.weixin.qq.comCPU靠邊站!使用cuDF在GPU加速Pandas?mp.weixin.qq.com1000+倍!超強(qiáng)Python『向量化』數(shù)據(jù)處理提速攻略?mp.weixin.qq.comDatatable:Python數(shù)據(jù)分析提速高手,飛一般的感覺!?mp.weixin.qq.com量化投資與機(jī)器學(xué)習(xí)微信公眾號,是業(yè)內(nèi)垂直于Quant、MFE、Fintech、AI、ML等領(lǐng)域的量化類主流自媒體。公眾號擁有來自公募、私募、券商、期貨、銀行、保險資管、海外等眾多圈內(nèi)18W+關(guān)注者。每日發(fā)布行業(yè)前沿研究成果和最新量化資訊。
總結(jié)
以上是生活随笔為你收集整理的亿条数据读取工具_仅需1秒!搞定100万行数据:超强Python数据分析利器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果手机怎么设置时间24小时制_8款手机
- 下一篇: excel中vlookup函数的使用方法