使用multiprocessing处理pandas DataFrame时遇pickle错误求助
问题解决:multiprocessing pickle错误处理
错误原因
multiprocessing.pool.MaybeEncodingError 本质是因为进程间传递结果时需要通过pickle序列化,但你的process_with_deals函数处理过程中生成了**dict_values对象**,这种类型无法被pickle序列化,导致结果传递失败。
解决步骤
- 定位
dict_values生成位置:检查你处理DataFrame的代码,找到使用dict.values()的地方,将其转换为可序列化的list类型(list(dict.values()))。 - 验证序列化可行性:在函数中添加pickle测试,提前排查返回的DataFrame是否包含不可序列化元素。
- 确保返回对象纯净:返回的DataFrame中所有元素必须是可pickle的类型(如字符串、数字、列表等,避免lambda、生成器、dict_values这类特殊对象)。
修改后示例代码
import os import pickle import pandas as pd from multiprocessing import Pool def process_with_deals(file): # 读取目标Excel文件(注意拼接完整路径) file_path = os.path.join('E:\ALLDataCourts', file) df = pd.read_excel(file_path) # 示例处理逻辑:将dict.values()转为列表(替换成你的实际处理代码) sample_dict = {'key1': 'val1', 'key2': 'val2'} # 错误写法:df['new_col'] = sample_dict.values() df['new_col'] = list(sample_dict.values()) # 转为列表,支持序列化 # 执行你的其他处理逻辑... int_tot = df.drop(columns=['deals']) # 可选:提前验证是否可序列化,快速排查问题 try: pickle.dumps(int_tot) except pickle.PicklingError as e: print(f"文件[{file}]处理后的数据无法序列化:{str(e)}") raise return int_tot if __name__ == '__main__': exper = os.listdir('E:\ALLDataCourts')[:2] with Pool(2) as p: result = p.map(process_with_deals, exper) # 合并所有处理后的DataFrame total_db = pd.concat(result, ignore_index=True) # 保存总数据库 total_db.to_excel('总数据库.xlsx', index=False)
关键注意事项
- pandas DataFrame本身支持pickle,但如果其中嵌套了不可序列化的对象(如dict_values、lambda),就会触发错误。
- 单独测试单个文件的处理结果是否能被
pickle.dumps()序列化,是快速定位问题的有效方法。
内容的提问来源于stack exchange,提问作者kremidzu
相关产品推荐
相关产品推荐

