咨询pandas.DataFrame.itertuples在ProcessPool进程池中无法运行的原因
问题原因
进程池跨进程传递参数时,需要将对象序列化(pickle)后再传给子进程,子进程再反序列化还原对象。而pandas.DataFrame.itertuples返回的是pandas动态生成的命名元组类实例,该类没有在模块顶层定义,子进程反序列化时找不到对应的类定义,会静默失败,因此没有任何输出。
而iterrows返回的是(索引, Series对象)的组合,二者都是Python标准可序列化对象,所以可以正常跨进程传递。线程池共享主进程的内存空间,不需要跨进程序列化,因此itertuples在线程池中可以正常运行。
解决方案
核心思路是避免直接传递itertuples生成的动态命名元组给子进程,可选方案如下:
- 方案1:提前将itertuples的结果转为标准可序列化对象,再传入进程池
提前把每行命名元组转成字典,再作为迭代参数传给进程池,对应修改代码如下:# 提前将命名元组转为字典列表 tuple_rows = [row._asdict() for row in df.itertuples()] # 修改from_itertuples方法适配字典输入 @classmethod def from_itertuples(cls, *args, **kwargs) -> 'Data': *args, row_dict = args return cls(*args, **kwargs, params=row_dict) # 调用进程池 process_pool(Data.from_itertuples, tuple_rows, 2, 100, 200, 300, a=10, b=20, c=30) - 方案2:将DataFrame分块后传给子进程,在子进程内部调用itertuples做遍历处理,完全避免跨进程传递动态命名元组。
- 方案3(仅适用于Linux/macOS):将进程启动方式改为
fork,共享主进程的内存空间,不需要完整序列化动态类,但该方式不支持Windows,且存在线程安全隐患,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Idan Hazan
相关产品推荐
相关产品推荐

