背景不多,我已经继承了公司用Python编写的一段代码,我真的不知道,该代码使用熊猫将很少的预下载Excel报告合并为一个。我一直遇到内存分配错误:
内存错误:无法为形状(17、5668350)和数据类型为对象的数组分配368. MiB。
这是给我错误的代码:
dfCC = dfVendNew.merge(dfVendOld[['SAP ID', 'Cost ctr']], on='SAP ID', how='left')
我被困在这一点上,无法进一步发展。我尝试更改Windows上的页面大小,但没有帮助。我怀疑这与我的计算机设置有关,因为此脚本可以在其他计算机上顺利运行。
非常感谢您的帮助。
答案 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。
希望这会有所帮助。