溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用pandas分析大型數(shù)據(jù)集

發(fā)布時(shí)間:2021-11-30 15:00:23 來源:億速云 閱讀:193 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要介紹如何使用pandas分析大型數(shù)據(jù)集,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

1.  簡(jiǎn)介

pandas雖然是個(gè)非常流行的數(shù)據(jù)分析利器,但很多朋友在使用pandas處理較大規(guī)模的數(shù)據(jù)集的時(shí)候經(jīng)常會(huì)反映pandas運(yùn)算“慢”,且內(nèi)存開銷“大”。

特別是很多學(xué)生黨在使用自己性能一般的筆記本嘗試處理大型數(shù)據(jù)集時(shí),往往會(huì)被捉襟見肘的算力所勸退。但其實(shí)只要掌握一定的pandas使用技巧,配置一般的機(jī)器也有能力hold住大型數(shù)據(jù)集的分析。

如何使用pandas分析大型數(shù)據(jù)集

圖1

本文就將以真實(shí)數(shù)據(jù)集和運(yùn)存16G的普通筆記本電腦為例,演示如何運(yùn)用一系列策略實(shí)現(xiàn)多快好省地用pandas分析大型數(shù)據(jù)集。

2. pandas多快好省策略

我們使用到的數(shù)據(jù)集來自kaggle上的「TalkingData AdTracking Fraud Detection  Challenge」競(jìng)賽( https://www.kaggle.com/c/talkingdata-adtracking-fraud-detection  ),使用到其對(duì)應(yīng)的訓(xùn)練集,這是一個(gè)大小有7.01G的csv文件。

下面我們將循序漸進(jìn)地探索在內(nèi)存開銷和計(jì)算時(shí)間成本之間尋求平衡,首先我們不做任何優(yōu)化,直接使用pandas的read_csv()來讀取train.csv文件:

import pandas as pd  raw = pd.read_csv('train.csv')  # 查看數(shù)據(jù)框內(nèi)存使用情況 raw.memory_usage(deep=True)

如何使用pandas分析大型數(shù)據(jù)集

圖2

可以看到首先我們讀入整個(gè)數(shù)據(jù)集所花費(fèi)的時(shí)間達(dá)到了將近三分鐘,且整個(gè)過程中因?yàn)橹虚g各種臨時(shí)變量的創(chuàng)建,一度快要撐爆我們16G的運(yùn)行內(nèi)存空間。

這樣一來我們后續(xù)想要開展進(jìn)一步的分析可是說是不可能的,因?yàn)殡S便一個(gè)小操作就有可能會(huì)因?yàn)橹虚g過程大量的臨時(shí)變量而撐爆內(nèi)存,導(dǎo)致死機(jī)藍(lán)屏,所以我們第一步要做的是降低數(shù)據(jù)框所占的內(nèi)存:

(1) 指定數(shù)據(jù)類型以節(jié)省內(nèi)存

因?yàn)閜andas默認(rèn)情況下讀取數(shù)據(jù)集時(shí)各個(gè)字段確定數(shù)據(jù)類型時(shí)不會(huì)替你優(yōu)化內(nèi)存開銷,比如我們下面利用參數(shù)nrows先讀入數(shù)據(jù)集的前1000行試探著看看每個(gè)字段都是什么類型:

raw = pd.read_csv('train.csv', nrows=1000) raw.info()

如何使用pandas分析大型數(shù)據(jù)集

圖3

怪不得我們的數(shù)據(jù)集讀進(jìn)來會(huì)那么的大,原來所有的整數(shù)列都轉(zhuǎn)換為了int64來存儲(chǔ),事實(shí)上我們?cè)瓟?shù)據(jù)集中各個(gè)整數(shù)字段的取值范圍根本不需要這么高的精度來存儲(chǔ),因此我們利用dtype參數(shù)來降低一些字段的數(shù)值精度:

raw = pd.read_csv('train.csv', nrows=1000,                   dtype={                       'ip': 'int32',                       'app': 'int16',                       'device': 'int16',                       'os': 'int16',                       'channel': 'int16',                       'is_attributed': 'int8'                   }) raw.info()

如何使用pandas分析大型數(shù)據(jù)集

圖4

可以看到,在修改數(shù)據(jù)精度之后,前1000行數(shù)據(jù)集的內(nèi)存大小被壓縮了將近54.6%,這是個(gè)很大的進(jìn)步,按照這個(gè)方法我們嘗試著讀入全量數(shù)據(jù)并查看其info()信息:

如何使用pandas分析大型數(shù)據(jù)集

圖5

可以看到隨著我們對(duì)數(shù)據(jù)精度的優(yōu)化,數(shù)據(jù)集所占內(nèi)存有了非??捎^的降低,使得我們開展進(jìn)一步的數(shù)據(jù)分析更加順暢,比如分組計(jì)數(shù):

(     raw     # 按照app和os分組計(jì)數(shù)     .groupby(['app', 'os'])     .agg({'ip': 'count'}) )

如何使用pandas分析大型數(shù)據(jù)集

圖6

那如果數(shù)據(jù)集的數(shù)據(jù)類型沒辦法優(yōu)化,那還有什么辦法在不撐爆內(nèi)存的情況下完成計(jì)算分析任務(wù)呢?

(2) 只讀取需要的列

如果我們的分析過程并不需要用到原數(shù)據(jù)集中的所有列,那么就沒必要全讀進(jìn)來,利用usecols參數(shù)來指定需要讀入的字段名稱:

raw = pd.read_csv('train.csv', usecols=['ip', 'app', 'os']) raw.info()

如何使用pandas分析大型數(shù)據(jù)集

圖7

可以看到,即使我們沒有對(duì)數(shù)據(jù)精度進(jìn)行優(yōu)化,讀進(jìn)來的數(shù)據(jù)框大小也只有4.1個(gè)G,如果配合上數(shù)據(jù)精度優(yōu)化效果會(huì)更好:

如何使用pandas分析大型數(shù)據(jù)集

圖8

如果有的情況下我們即使優(yōu)化了數(shù)據(jù)精度又篩選了要讀入的列,數(shù)據(jù)量依然很大的話,我們還可以以分塊讀入的方式來處理數(shù)據(jù):

(3) 分塊讀取分析數(shù)據(jù)

利用chunksize參數(shù),我們可以為指定的數(shù)據(jù)集創(chuàng)建分塊讀取IO流,每次最多讀取設(shè)定的chunksize行數(shù)據(jù),這樣我們就可以把針對(duì)整個(gè)數(shù)據(jù)集的任務(wù)拆分為一個(gè)一個(gè)小任務(wù)最后再匯總結(jié)果:

from tqdm.notebook import tqdm  # 在降低數(shù)據(jù)精度及篩選指定列的情況下,以1千萬行為塊大小 raw = pd.read_csv('train.csv',                    dtype={                       'ip': 'int32',                       'app': 'int16',                       'os': 'int16'                   },                   usecols=['ip', 'app', 'os'],                   chunksize=10000000)  # 從raw中循環(huán)提取每個(gè)塊并進(jìn)行分組聚合,最后再匯總結(jié)果 result = \ (     pd     .concat([chunk              .groupby(['app', 'os'], as_index=False)              .agg({'ip': 'count'}) for chunk in tqdm(raw)])     .groupby(['app', 'os'])     .agg({'ip': 'sum'}) )  result

如何使用pandas分析大型數(shù)據(jù)集

圖9

可以看到,利用分塊讀取處理的策略,從始至終我們都可以保持較低的內(nèi)存負(fù)載壓力,并且一樣完成了所需的分析任務(wù),同樣的思想,如果你覺得上面分塊處理的方式有些費(fèi)事,那下面我們就來上大招:

(4) 利用dask替代pandas進(jìn)行數(shù)據(jù)分析

dask相信很多朋友都有聽說過,它的思想與上述的分塊處理其實(shí)很接近,只不過更加簡(jiǎn)潔,且對(duì)系統(tǒng)資源的調(diào)度更加智能,從單機(jī)到集群,都可以輕松擴(kuò)展伸縮。

如何使用pandas分析大型數(shù)據(jù)集

圖10

推薦使用conda install dask來安裝dask相關(guān)組件,安裝完成后,我們僅僅需要需要將import pandas as pd替換為import  dask.dataframe as dd,其他的pandas主流API使用方式則完全兼容,幫助我們無縫地轉(zhuǎn)換代碼:

如何使用pandas分析大型數(shù)據(jù)集

圖11

可以看到整個(gè)讀取過程只花費(fèi)了313毫秒,這當(dāng)然不是真的讀進(jìn)了內(nèi)存,而是dask的延時(shí)加載技術(shù),這樣才有能力處理「超過內(nèi)存范圍的數(shù)據(jù)集」。

接下來我們只需要像操縱pandas的數(shù)據(jù)對(duì)象一樣正常書寫代碼,最后加上.compute(),dask便會(huì)基于前面搭建好的計(jì)算圖進(jìn)行正式的結(jié)果運(yùn)算:

(     raw     # 按照app和os分組計(jì)數(shù)     .groupby(['app', 'os'])     .agg({'ip': 'count'})     .compute() # 激活計(jì)算圖 )

并且dask會(huì)非常智能地調(diào)度系統(tǒng)資源,使得我們可以輕松跑滿所有CPU:

如何使用pandas分析大型數(shù)據(jù)集

圖12

關(guān)于dask的更多知識(shí)可以移步官網(wǎng)自行學(xué)習(xí)( https://docs.dask.org/en/latest/ )。

如何使用pandas分析大型數(shù)據(jù)集

圖13

以上是“如何使用pandas分析大型數(shù)據(jù)集”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI