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

时间:2020-02-17 09:21:43

标签: python pandas

背景不多,我已经继承了公司用Python编写的一段代码,我真的不知道,该代码使用熊猫将很少的预下载Excel报告合并为一个。我一直遇到内存分配错误:

内存错误:无法为形状(17、5668350)和数据类型为对象的数组分配368. MiB。

这是给我错误的代码:

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

我被困在这一点上,无法进一步发展。我尝试更改Windows上的页面大小,但没有帮助。我怀疑这与我的计算机设置有关,因为此脚本可以在其他计算机上顺利运行。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

您可以尝试按块处理和合并数据帧,这是我的尝试:

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以减轻您的记忆力。

答案 1 :(得分:2)

对象将是存储事物列表的最胖方法。但是您需要了解一些有关如何存储和缩小存储空间的知识。 使用数据框的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是对象类,消息也是。另一件事要看的是最后一行:内存使用情况。因此,现在您可以更改数据类型并查看内存使用情况的下降。因此,让我们看一下如何更改其中一些类型。

默认情况下,您的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.categorical,然后查看使用此命令可以节省多少内存。

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

查看使用astype here的文档 下一步移动将首先正确地导入它。当您读取excel文件时,请使用converters argument in read_excel

如果仍然需要降低内存使用量(这不应该只与Excel记录有关),则可以使用其他分布式技术,即Dask

希望这会有所帮助。