自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

多快好省地使用pandas分析大型數(shù)據(jù)集

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

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ù)集的分析。

圖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文件:

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

圖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è)字段都是什么類型:

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

圖3

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

  1. raw = pd.read_csv('train.csv', nrows=1000
  2.                   dtype={ 
  3.                       'ip': 'int32', 
  4.                       'app': 'int16', 
  5.                       'device': 'int16', 
  6.                       'os': 'int16', 
  7.                       'channel': 'int16', 
  8.                       'is_attributed': 'int8' 
  9.                   }) 
  10. raw.info() 

圖4

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

圖5

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

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

圖6

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

(2) 只讀取需要的列

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

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

圖7

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

圖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é)果:

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

圖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ò)展伸縮。

圖10

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

圖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)算:

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

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

圖12

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

圖13

 

責(zé)任編輯:趙寧寧 來源: Python大數(shù)據(jù)分析
相關(guān)推薦

2009-05-05 08:50:10

ITIL運(yùn)維管理摩卡

2025-04-11 11:14:51

2013-09-04 11:17:52

移動(dòng)Web App

2009-02-06 09:25:00

網(wǎng)絡(luò)設(shè)備參數(shù)配置

2022-08-25 18:58:48

MLOps

2015-07-08 15:24:59

中小型醫(yī)院IT系統(tǒng)華為

2011-01-06 16:52:48

曙光機(jī)架式服務(wù)器

2013-05-09 10:32:12

翠微小學(xué)Windows Ser微軟

2013-04-28 13:33:38

翠微小學(xué)Windows Ser

2011-08-21 08:27:23

明基掃描儀

2020-09-11 10:54:54

云計(jì)算

2011-05-04 17:44:48

連續(xù)供墨系統(tǒng)

2018-08-02 15:49:54

聯(lián)想

2011-12-19 09:07:58

S5024P-EI交換機(jī)

2021-12-13 10:12:46

CIO低代碼軟件開發(fā)

2014-09-19 09:23:16

天地超云云服務(wù)器

2014-09-19 09:27:48

天地超云云服務(wù)器

2022-08-27 12:13:05

人工智能MLOps

2024-11-26 08:00:00

SQLPandasPandaSQL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)