pandas合并两个DataFrame时触发MemoryError内存不足报错求解
问题解决:Pandas merge操作触发MemoryError内存溢出问题
报错信息如下:
numpy.core._exceptions.MemoryError: Unable to allocate 58.1 GiB for an array with shape (7791676634,) and data type int64
该报错核心原因是两个表的关联键CUSTKEY存在大量重复值,merge时生成了笛卡尔积,1200万条的交易表和90万条的员工表关联后生成了77亿条结果,远超内存容量。你需要实现的Excel VLOOKUP效果是一对多匹配(同一个客户键在员工表只匹配1条,交易表保留多条),可以按以下方案解决:
- 方案1:优先使用map映射实现匹配(内存占用最低,完全避免笛卡尔积)
因为仅需要新增2个字段,直接将员工表的关联字段转为字典映射,再给交易表匹配赋值即可,代码如下:# 先对员工表按CUSTKEY去重,保证一个键只对应一条记录 Select_Emp_df = Emp_df[['CUSTKEY','GCIF_GENDER_DSC','SEX']].drop_duplicates('CUSTKEY', keep='first') # 生成映射字典 gender_map = Select_Emp_df.set_index('CUSTKEY')['GCIF_GENDER_DSC'].to_dict() sex_map = Select_Emp_df.set_index('CUSTKEY')['SEX'].to_dict() # 匹配赋值给Big_df Big_df['GCIF_GENDER_DSC'] = Big_df['CUSTKEY'].map(gender_map) Big_df['SEX'] = Big_df['CUSTKEY'].map(sex_map) - 方案2:仍使用merge的场景,提前校验键唯一性避免笛卡尔积
合并前先对员工表的CUSTKEY去重,合并时添加校验参数,明确是多对一匹配:# 员工表去重 Select_Emp_df = Emp_df[['CUSTKEY','GCIF_GENDER_DSC','SEX']].drop_duplicates('CUSTKEY', keep='first') # 合并时指定多对一校验,出现重复键会直接抛出异常提示 Big_df = pd.merge(Big_df, Select_Emp_df, on='CUSTKEY', how='left', validate='m:1') - 方案3:额外优化内存占用的通用手段
- 优化字段数据类型:将数值型字段用
pd.to_numeric(downcast=)压缩,字符串分类字段转category类型,可减少50%以上的内存占用 - 不需要的字段提前删除:读取csv时就指定
usecols参数只加载需要的列,避免无用字段占用内存
# 示例:读取交易表时只加载需要的列 df2019 = pd.read_csv('U21_02767G - Customer Trade Info2019.csv', low_memory=False, usecols=['需要的列1','需要的列2','CUSTKEY']) - 优化字段数据类型:将数值型字段用
内容的提问来源于stack exchange,提问作者Shri
相关产品推荐
相关产品推荐

