熱線電話:13121318867

登錄
首頁精彩閱讀2000字詳解,當Pandas遇上超大規模的數據集該如何處理呢?(CDA內容分享)
2000字詳解,當Pandas遇上超大規模的數據集該如何處理呢?(CDA內容分享)
2021-12-14
收藏

作者: 俊欣

來源:關于數據分析與可視化

大家好,又是新的一周。大家一般會用Pandas模塊來對數據集進行進一步的分析與挖掘關鍵信息,但是當我們遇到數據集特別特別大的時候,內存就會爆掉,今天小編就來分享幾個技巧,來幫助你避免遇到上述提到的這個情況。

read_csv()方法當中的chunksize參數

read_csv()方法當中的chunksize參數顧名思義就是對于超大csv文件,我們可以分塊來進行讀取,例如文件當中有7000萬行的數據,我們將chunksize參數設置為100萬,每次分100萬來分批讀取,代碼如下

# read the large csv file with specified chunksize  df_chunk = pd.read_csv(r'data.csv', chunksize=1000000)

這時我們得到的df_chunk并非是一個DataFrame對象,而是一個可迭代的對象。接下來我們使用for循環并且將自己創立數據預處理的函數方法作用于每塊的DataFrame數據集上面,代碼如下

chunk_list = []  # 創建一個列表chunk_list   # for循環遍歷df_chunk當中的每一個DataFrame對象 for chunk in df_chunk:   # 將自己創建的數據預處理的方法作用于每個DataFrame對象上 chunk_filter = chunk_preprocessing(chunk)  # 將處理過后的結果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']]

當然我們要去除掉空值可以調用df.dropna()方法,一般也可以提高數據的準確性以及減少內存的消耗

轉變數據格式

最后我們可以通過改變數據類型壓縮內存空間,一般情況下,Pandas模塊會給數據列自動設置默認的數據類型,很多數據類型里面還有子類型,而這些子類型可以用更加少的字節數來表示,下表給出了各子類型所占的字節數

2000字詳解,當Pandas遇上超大規模的數據集該如何處理呢?

對于內存當中的數據,我們可以這么來理解,內存相當于是倉庫,而數據則相當于是貨物,貨物在入倉庫之前呢需要將其裝入箱子當中,現在有著大、中、小三種箱子,

2000字詳解,當Pandas遇上超大規模的數據集該如何處理呢?

現在Pandas在讀取數據的時候是將這些數據無論其類型,都是裝到大箱子當中去,因此會在很快的時間里倉庫也就是內存就滿了。

因此我們優化的思路就在于是遍歷每一列,然后找出該列的最大值與最小值,我們將這些最大最小值與子類型當中的最大最小值去做比較,挑選字節數最小的子類型。

我們舉個例子,Pandas默認是int64類型的某一列最大值與最小值分別是0和100,而int8類型是可以存儲數值在-128~127之間的,因此我們可以將該列從int64類型轉換成int8類型,也就同時節省了不少內存的空間。

我們將上面的思路整理成代碼,就是如下所示

def reduce_mem_usage(df): """ 遍歷DataFrame數據集中的每列數據集
    并且更改它們的數據類型        
    """ start_memory = df.memory_usage().sum() / 1024**2 print('DataFrame所占用的數據集有: {:.2f} MB'.format(start_memory)) for col in df.columns:
        col_type = df[col].dtype if 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**2 print('優化過之后數據集的內存占有: {:.2f} MB'.format(end_memory))
    print('減少了大約有: {:.1f}%'.format(100 * (start_memory - end_memory) / start_memory)) return df

大家可以將小編寫的這個函數方法拿去嘗試一番,看一下效果如何?


數據分析咨詢請掃描二維碼

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

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢