2000字详解 当Pandas遇上超大规模的数据集该如何处理呢?
大家好,大家一般會用Pandas模塊來對數(shù)據(jù)集進行進一步的分析與挖掘關(guān)鍵信息,但是當我們遇到數(shù)據(jù)集特別特別大的時候,內(nèi)存就會爆掉,今天小編就來分享幾個技巧,來幫助你避免遇到上述提到的這個情況。
read_csv()方法當中的chunksize參數(shù)
read_csv()方法當中的chunksize參數(shù)顧名思義就是對于超大csv文件,我們可以分塊來進行讀取,例如文件當中有7000萬行的數(shù)據(jù),我們將chunksize參數(shù)設(shè)置為100萬,每次分100萬來分批讀取,代碼如下
#?read?the?large?csv?file?with?specified?chunksize? df_chunk?=?pd.read_csv(r'data.csv',?chunksize=1000000)這時我們得到的df_chunk并非是一個DataFrame對象,而是一個可迭代的對象。接下來我們使用for循環(huán)并且將自己創(chuàng)立數(shù)據(jù)預(yù)處理的函數(shù)方法作用于每塊的DataFrame數(shù)據(jù)集上面,代碼如下
chunk_list?=?[]??#?創(chuàng)建一個列表chunk_list?#?for循環(huán)遍歷df_chunk當中的每一個DataFrame對象 for?chunk?in?df_chunk:??#?將自己創(chuàng)建的數(shù)據(jù)預(yù)處理的方法作用于每個DataFrame對象上chunk_filter?=?chunk_preprocessing(chunk)#?將處理過后的結(jié)果append到上面建立的空列表當中chunk_list.append(chunk_filter)#?然后將列表concat到一塊兒 df_concat?=?pd.concat(chunk_list)將不重要的列都去除掉
當然我們還可以進一步將不重要的列都給去除掉,例如某一列當中存在較大比例的空值,那么我們就可以將該列去除掉,代碼如下
#?Filter?out?unimportant?columns df?=?df[['col_1','col_2',?'col_3',?'col_4',?'col_5',?'col_6','col_7',?'col_8',?'col_9',?'col_10']]當然我們要去除掉空值可以調(diào)用df.dropna()方法,一般也可以提高數(shù)據(jù)的準確性以及減少內(nèi)存的消耗
轉(zhuǎn)變數(shù)據(jù)格式
最后我們可以通過改變數(shù)據(jù)類型來壓縮內(nèi)存空間,一般情況下,Pandas模塊會給數(shù)據(jù)列自動設(shè)置默認的數(shù)據(jù)類型,很多數(shù)據(jù)類型里面還有子類型,而這些子類型可以用更加少的字節(jié)數(shù)來表示,下表給出了各子類型所占的字節(jié)數(shù)
對于內(nèi)存當中的數(shù)據(jù),我們可以這么來理解,內(nèi)存相當于是倉庫,而數(shù)據(jù)則相當于是貨物,貨物在入倉庫之前呢需要將其裝入箱子當中,現(xiàn)在有著大、中、小三種箱子,
現(xiàn)在Pandas在讀取數(shù)據(jù)的時候是將這些數(shù)據(jù)無論其類型,都是裝到大箱子當中去,因此會在很快的時間里倉庫也就是內(nèi)存就滿了。
因此我們優(yōu)化的思路就在于是遍歷每一列,然后找出該列的最大值與最小值,我們將這些最大最小值與子類型當中的最大最小值去做比較,挑選字節(jié)數(shù)最小的子類型。
我們舉個例子,Pandas默認是int64類型的某一列最大值與最小值分別是0和100,而int8類型是可以存儲數(shù)值在-128~127之間的,因此我們可以將該列從int64類型轉(zhuǎn)換成int8類型,也就同時節(jié)省了不少內(nèi)存的空間。
我們將上面的思路整理成代碼,就是如下所示
def?reduce_mem_usage(df):"""?遍歷DataFrame數(shù)據(jù)集中的每列數(shù)據(jù)集并且更改它們的數(shù)據(jù)類型????????"""start_memory?=?df.memory_usage().sum()?/?1024**2print('DataFrame所占用的數(shù)據(jù)集有:?{:.2f}?MB'.format(start_memory))for?col?in?df.columns:col_type?=?df[col].dtypeif?col_type?!=?object:col_min?=?df[col].min()col_max?=?df[col].max()if?str(col_type)[:3]?==?'int':if?col_min?>?np.iinfo(np.int8).min?and?col_max?<?np.iinfo(np.int8).max:df[col]?=?df[col].astype(np.int8)elif?col_min?>?np.iinfo(np.int16).min?and?col_max?<?np.iinfo(np.int16).max:df[col]?=?df[col].astype(np.int16)elif?col_min?>?np.iinfo(np.int32).min?and?col_max?<?np.iinfo(np.int32).max:df[col]?=?df[col].astype(np.int32)elif?col_min?>?np.iinfo(np.int64).min?and?col_max?<?np.iinfo(np.int64).max:df[col]?=?df[col].astype(np.int64)??else:if?col_min?>?np.finfo(np.float16).min?and?col_max?<?np.finfo(np.float16).max:df[col]?=?df[col].astype(np.float16)elif?col_min?>?np.finfo(np.float32).min?and?col_max?<?np.finfo(np.float32).max:df[col]?=?df[col].astype(np.float32)else:df[col]?=?df[col].astype(np.float64)end_memory?=?df.memory_usage().sum()?/?1024**2print('優(yōu)化過之后數(shù)據(jù)集的內(nèi)存占有:?{:.2f}?MB'.format(end_memory))print('減少了大約有:?{:.1f}%'.format(100?*?(start_memory?-?end_memory)?/?start_memory))return?df大家可以將小編寫的這個函數(shù)方法拿去嘗試一番,看一下效果如何?!
各位伙伴們好,詹帥本帥搭建了一個個人博客和小程序,匯集各種干貨和資源,也方便大家閱讀,感興趣的小伙伴請移步小程序體驗一下哦!(歡迎提建議)
推薦閱讀
牛逼!Python常用數(shù)據(jù)類型的基本操作(長文系列第①篇)
牛逼!Python的判斷、循環(huán)和各種表達式(長文系列第②篇)
牛逼!Python函數(shù)和文件操作(長文系列第③篇)
牛逼!Python錯誤、異常和模塊(長文系列第④篇)
總結(jié)
以上是生活随笔為你收集整理的2000字详解 当Pandas遇上超大规模的数据集该如何处理呢?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 实现循环的最快方式(for
- 下一篇: 实战:Python 轻松实现自动化谷歌翻