99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀6種數(shù)據(jù)格式對比,用Jupyter+pandas高效數(shù)據(jù)分析
6種數(shù)據(jù)格式對比,用Jupyter+pandas高效數(shù)據(jù)分析
2020-10-27
收藏

編譯:劉早起(有刪改)

來源:towardsdatascience、GitHub等

在使用python進(jìn)行數(shù)據(jù)分析時,Jupyter Notebook是一個非常強(qiáng)力的工具,在數(shù)據(jù)集不是很大的情況下,我們可以使用pandas輕松對txt或csv等純文本格式數(shù)據(jù)進(jìn)行讀寫。

然而當(dāng)數(shù)據(jù)集的維度或者體積很大時,將數(shù)據(jù)保存并加載回內(nèi)存的過程就會變慢,并且每次啟動Jupyter Notebook時都需要等待一段時間直到數(shù)據(jù)重新加載, 這樣csv格式或任何其他純文本格式數(shù)據(jù)都失去了吸引力。

本文將對pandas支持的多種格式數(shù)據(jù)在處理數(shù)據(jù)的不同方面進(jìn)行比較,包含I/O速度、內(nèi)存消耗、磁盤占用空間等指標(biāo),試圖找出如何為我們的數(shù)據(jù)找到一個合適的格式的辦法!

——格式說明

現(xiàn)在對本文進(jìn)行對比的幾種數(shù)據(jù)格式進(jìn)行說明。

  • CSV:最常用的數(shù)據(jù)格式
  • Pickle:用于序列化和反序列化Python對象結(jié)構(gòu)
  • MessagePack:類似于json,但是更小更塊
  • HDF5:一種常見的跨平臺數(shù)據(jù)儲存文件
  • Feather:一個快速、輕量級的存儲框架
  • Parquet:Apache Hadoop的列式存儲格式

——指標(biāo)說明

為了找到格式來存儲數(shù)據(jù),本文選擇以下指標(biāo)進(jìn)行對比。

  • size_mb:帶有序列化數(shù)據(jù)幀的文件的大小
  • save_time:將數(shù)據(jù)幀保存到磁盤所需的時間
  • load_time:將先前轉(zhuǎn)儲的數(shù)據(jù)幀加載到內(nèi)存所需的時間
  • save_ram_delta_mb:在數(shù)據(jù)幀保存過程中最大的內(nèi)存消耗增長
  • load_ram_delta_mb:數(shù)據(jù)幀加載過程中最大的內(nèi)存消耗增長

注意,當(dāng)我們使用有效壓縮的二進(jìn)制數(shù)據(jù)格式(例如Parquet)時,最后兩個指標(biāo)變得非常重要。它們可以幫助我們估算加載串行化數(shù)據(jù)所需的RAM數(shù)量,以及數(shù)據(jù)大小本身。我們將在下一部分中更詳細(xì)地討論這個問題。

——對比

現(xiàn)在開始對前文介紹的5種數(shù)據(jù)格式進(jìn)行比較,為了更好地控制序列化的數(shù)據(jù)結(jié)構(gòu)和屬性我們將使用自己生成的數(shù)據(jù)集。

下面是生成測試數(shù)據(jù)的代碼,我們隨機(jī)生成具有數(shù)字和分類特征的數(shù)據(jù)集。數(shù)值特征取自標(biāo)準(zhǔn)正態(tài)分布。分類特征以基數(shù)為C的uuid4隨機(jī)字符串生成,其中2 <= C <= max_cat_size。

def?generate_dataset(n_rows,?num_count,?cat_count,?max_nan=0.1,?max_cat_size=100):

????dataset,?types?=?{},?{}
????
????def?generate_categories():
????????from?uuid?import?uuid4
????????category_size?=?np.random.randint(2,?max_cat_size)
????????return?[str(uuid4())?for?_?in?range(category_size)]
????
????for?col?in?range(num_count):
????????name?=?f'n{col}'
????????values?=?np.random.normal(0,?1,?n_rows)
????????nan_cnt?=?np.random.randint(1,?int(max_nan*n_rows))
????????index?=?np.random.choice(n_rows,?nan_cnt,?replace=False)
????????values[index]?=?np.nan
????????dataset[name]?=?values
????????types[name]?=?'float32'
????????
????for?col?in?range(cat_count):
????????name?=?f'c{col}'
????????cats?=?generate_categories()
????????values?=?np.array(np.random.choice(cats,?n_rows,?replace=True),?dtype=object)
????????nan_cnt?=?np.random.randint(1,?int(max_nan*n_rows))
????????index?=?np.random.choice(n_rows,?nan_cnt,?replace=False)
????????values[index]?=?np.nan
????????dataset[name]?=?values
????????types[name]?=?'object'
????
????return?pd.DataFrame(dataset),?types

現(xiàn)在我們以CSV文件保存和加載的性能作為基準(zhǔn)。將五個隨機(jī)生成的具有百萬個觀測值的數(shù)據(jù)集轉(zhuǎn)儲到CSV中,然后讀回內(nèi)存以獲取平均指標(biāo)。并且針對具有相同行數(shù)的20個隨機(jī)生成的數(shù)據(jù)集測試了每種二進(jìn)制格式。

同時使用兩種方法進(jìn)行對比:

1.以字符串作為分類特征

下圖顯示了每種數(shù)據(jù)格式的平均I/O時間。這里有趣的發(fā)現(xiàn)是hdf的加載速度比csv更低,而其他二進(jìn)制格式的性能明顯更好,而feather和parquet則表現(xiàn)的非常好

保存數(shù)據(jù)并從磁盤讀取數(shù)據(jù)時的內(nèi)存消耗如何?下一張圖片向我們展示了hdf的性能再次不那么好。但可以肯定的是,csv不需要太多額外的內(nèi)存來保存/加載純文本字符串,而feather和parquet則非常接近

最后,讓我們看一下文件大小的對比。這次parquet顯示出非常好的結(jié)果,考慮到這種格式是為有效存儲大量數(shù)據(jù)而開發(fā)的,也是理所當(dāng)然

2.對特征進(jìn)行轉(zhuǎn)換

在上一節(jié)中,我們沒有嘗試有效地存儲分類特征,而是使用純字符串,接下來我們使用專用的pandas.Categorical類型再次進(jìn)行比較。

從上圖可以看到,與純文本csv相比,所有二進(jìn)制格式都可以顯示其真強(qiáng)大功能,效率遠(yuǎn)超過csv,因此我們將其刪除以更清楚地看到各種二進(jìn)制格式之間的差異。

可以看到feather和pickle擁有最快的I/O速度,接下來該比較數(shù)據(jù)加載過程中的內(nèi)存消耗了。下面的條形圖顯示了我們之前提到的有關(guān)parquet格式的情況

為什么parquet內(nèi)存消耗這么高?因為只要在磁盤上占用一點(diǎn)空間,就需要額外的資源才能將數(shù)據(jù)解壓縮回數(shù)據(jù)幀。即使文件在持久性存儲磁盤上需要適度的容量,也可能無法將其加載到內(nèi)存中。

最后我們看下不同格式的文件大小比較。所有格式都顯示出良好的效果,除了hdf仍然需要比其他格式更多的空間。

??結(jié)論

正如我們的上面的測試結(jié)果所示,feather格式似乎是在多個Jupyter之間存儲數(shù)據(jù)的理想選擇。它顯示出很高的I/O速度,不占用磁盤上過多的內(nèi)存,并且在裝回RAM時不需要任何拆包。

當(dāng)然這種比較并不意味著我們應(yīng)該在每種情況下都使用這種格式。例如,不希望將feather格式用作長期文件存儲。此外,當(dāng)其他格式發(fā)揮最佳效果時,它并未考慮所有可能的情況。所以我們也需要根據(jù)具體情況進(jìn)行選擇!


——熱門課程推薦:

想從事業(yè)務(wù)型數(shù)據(jù)分析師,您可以點(diǎn)擊>>>“數(shù)據(jù)分析師”了解課程詳情;

想從事數(shù)據(jù)分析師,您可以點(diǎn)擊>>>“大數(shù)據(jù)就業(yè)”了解課程詳情;

想成為人工智能工程師,您可以點(diǎn)擊>>>“人工智能就業(yè)”了解課程詳情;

想了解Python數(shù)據(jù)分析,您可以點(diǎn)擊>>>“Python數(shù)據(jù)分析師”了解課程詳情;

想咨詢互聯(lián)網(wǎng)運(yùn)營,你可以點(diǎn)擊>>>互聯(lián)網(wǎng)運(yùn)營就業(yè)班”了解課程詳情;

想了解更多優(yōu)質(zhì)課程,請點(diǎn)擊>>>

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時表示是新驗證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }