簡體   English   中英

大型 Pandas 數據框的 Python 內存錯誤

[英]Python Memory Error with a large Pandas Dataframe

你能幫我回憶一下嗎?

我低於內存錯誤。

文件“pandas_libs\\algos_common_helper.pxi”,第 361 行,在 pandas._libs.algos.ensure_int64 MemoryError

然后,我使用以下代碼輸出所有變量的所有內存:

def sizeof_fmt(num, suffix='B'):
    ''' by Fred Cirera,  https://stackoverflow.com/a/1094933/1870254, modified'''
    for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
        if abs(num) < 1024.0:
            return "%3.1f %s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.1f %s%s" % (num, 'Yi', suffix)

print('Memory size of each Varaible:')
for name, size in sorted(((name, sys.getsizeof(value)) for name, value in locals().items()),
                         key= lambda x: -x[1])[:10]:
    print("{:>30}: {:>8}".format(name, sizeof_fmt(size)))

Memory size of each Varaible:
                      df_baker: 572.6 MiB
                       df_hall: 37.5 MiB
                 df_WSGT_baker: 12.1 KiB
                  df_B12_baker: 12.1 KiB
                  df_WSGT_hall:  7.7 KiB
                   df_B12_hall:  7.7 KiB
                      __file__:  178.0 B
               __annotations__:  136.0 B
                         MyWho:   72.0 B
                    sizeof_fmt:   72.0 B

Pandas 數據幀 df_baker 的最大內存僅為 570MB。 我有 5GB 內存。 那為什么我有內存錯誤? 謝謝你的幫助。 我很感激。

我不認為你衡量你認為你衡量的東西。

引用sys.getsizeof()的文檔

以字節為單位返回對象的大小。 對象可以是任何類型的對象。 所有內置對象都將返回正確的結果,但對於第三方擴展,這不一定適用,因為它是特定於實現的。

只考慮直接歸因於對象的內存消耗而不是它所指對象的內存消耗

(Emph。我的)

因此,沒有直接從locals()引用的任何內容,函數內部分配的所有內容,都不會在此處顯示。

還有其他工具可以查看 Python 堆。 當參考圖不是樹時,理解內存消耗並不容易,我敢打賭,堆上有很多指向相同對象的多個鏈接。

無論如何,基本事實是您的 Python 進程(或 Windows 中的等價物)的 RSS 大小。 這是實際分配的數量,包括中間的所有內容,由 C 代碼 malloc 的所有內容(在 pandas / numpy 中很豐富)等。

Pandas 為您提供所需的內存使用情況,包括列中的 Python 對象(通常是字符串)使用的內存。 舉個例子

> df = pd.DataFrame({'a': ['a' * 100] * 100})
> sys.getsizeof(df)
15852
> df.info(memory_usage='deep')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 1 columns):
a    100 non-null object
dtypes: object(1)
memory usage: 15.5 KB

調用info可以獲得總內存; 您需要memory_usage=參數,因為默認參數為您提供不考慮字符串的淺內存使用情況。

要在程序中的任何點以import psutil, os顯示 RSS 內存,可以在import psutil, os后使用此函數

def usage():
    process = psutil.Process(os.getpid())
    return f'{process.memory_info()[0] / float(2 ** 20):,.1f}'  + ' MB'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM