如何解决Pandas的内存分配问题?

2024-05-14 13:33:19 发布

您现在位置:Python中文网/ 问答频道 /正文

小背景,我在公司继承了一段用Python编写的代码,我真的不知道,该代码使用pandas将几个预下载的Excel报表合并到一个报表中。我一直遇到内存分配错误:

内存错误:无法分配368。用于具有形状(175668350)和数据类型对象的数组的MiB

这是给出错误的代码:

dfCC = dfVendNew.merge(dfVendOld[['SAP ID', 'Cost ctr']], on='SAP ID', how='left')

我在这一点上进退两难,无法取得进一步进展。我曾尝试在Windows上更改页面大小,但没有效果。我怀疑这与我的计算机设置有关,因为此脚本在其他计算机上运行时没有任何问题

我将非常感谢任何帮助


Tags: 对象内存代码idpandas报表计算机错误
2条回答

您可以尝试在块中处理和合并数据帧,以下是我的尝试:

all_data = pd.DataFrame()
new = dfVendNew
old = dfVendOld[['SAP ID', 'Cost ctr']]
    for sap_id in np.array_split(new['SAP ID'].unique(), 10):
         new_chunk = new[new['SAP ID'].isin(sap_id)]
         old_chunk = old[old['SAP ID'].isin(sap_id)]
         merged = new_chunk.merge(old_chunk, on='SAP ID', how='left')
         all_data = pd.concat([merged, all_data], ignore_index=True, sort=False)

        del new_chunk
        del old_chunk
        del merged

    return all_data

首先获得新数据帧的唯一SAP ID,然后创建10个不同的SAP ID列表,然后根据这些列表拆分新数据帧和旧数据帧。合并每个块和del以释放内存

对象将成为存储事物列表的最胖的方式。但是你需要知道一些东西是如何存储的,这样才能使它更小更快。 使用dataframe的df.info()检查列类型

这是一个玩具示例:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
people     3 non-null object
cost_ctr    3 non-null object
number     3 non-null int64
dtypes: int64(1), object(2)
memory usage: 152.0+ bytes

在这种情况下,people是一个对象类,message也是。另一个要看的是最后一行:内存使用情况。因此,现在您可以更改数据类型并观察内存使用情况下降。让我们来看看如何改变其中的一些类型

默认情况下,您的SAP_ID可能是int。如果不是,并且都是数字数据,您可以使用:

df['SAP ID']=df['SAP ID'].astype(int)

df['SAP ID']=pd.to_numeric(df['SAP ID'])

现在您已经更改了一列的类型,请再次使用df.info()检查内存

“Cost-ctr”听起来像是一个很短的重复列表,但通常存储为字符串列表。您可以将此列更改为pd.category,并查看使用此命令可以节省多少内存

df['Cost_Ctr'] = df['Cost_Ctr'].astype(pd.Categorical)

查看有关使用astype here的文档 下一级移动首先要正确导入。读取excel文件时,请使用converters argument in read_excel

如果降低内存使用率仍然是一个问题(这不应该只针对Excel记录),那么可以使用其他分布式技术,即Dask

希望这有帮助

相关问题 更多 >

    热门问题