多进程环境下编辑pandas DataFrame时修改不生效问题如何解决
问题根因
multiprocessing启动的子进程拥有独立内存空间,Manager.Namespace存储pandas DataFrame这类非内置类型时,子进程调用d.df获取到的是原对象的副本,对副本做的修改默认不会同步回主进程的共享对象中。- 原代码末尾
data = d逻辑错误,直接将未修改的原始DataFrame赋值给data,覆盖了可能的同步结果。
最优解决方案:分块处理+结果合并
该方案不需要依赖共享对象同步,性能更高,是pandas多进程场景下的标准实现:
from multiprocessing import Pool import pandas as pd def process_block(block): # 此处替换为你实际的逐行处理逻辑 for index in block.index: # 按需修改字段值示例 block.loc[index, 'checked'] = 'yes' block.loc[index, 'phone'] = 'phone' return block if __name__ == '__main__': # 读取原始数据 d = pd.read_excel(r"final.xlsx") d['phone'] = 'none' d['checked'] = 'no' # 按10行一个块拆分DataFrame,总长度要和你原始数据匹配 block_size = 10 blocks = [d.iloc[i*block_size : (i+1)*block_size] for i in range(30)] # 启动进程池处理,进程数建议和CPU逻辑核心数保持一致,开太多反而会降低性能 with Pool(processes=8) as pool: processed_blocks = pool.map(process_block, blocks) # 合并所有处理完成的块得到最终结果 final_df = pd.concat(processed_blocks) print(final_df)
若坚持使用共享对象的修正写法
需要在子进程修改完副本后主动写回共享Namespace,同时加锁避免多进程写冲突:
from multiprocessing import Process, Manager, Lock import pandas as pd def f(d, lock, start, end): data = d.df for index in range(start, end): data.loc[index, 'checked'] = 'yes' data.loc[index, 'phone'] = 'phone' # 加锁后将修改后的副本写回共享对象 with lock: d.df = data if __name__ == '__main__': d = pd.read_excel(r"final.xlsx") d['phone'] = 'none' d['checked'] = 'no' mgr = Manager() data_namespace = mgr.Namespace() data_namespace.df = d # 引入锁避免多进程同时写共享对象导致数据损坏 lock = mgr.Lock() process_pool = [] start = 0 end = 10 for i in range(30): p = Process(target=f, args=(data_namespace, lock, start, end)) p.start() process_pool.append(p) start = end end = end + 10 for p in process_pool: p.join() # 直接读取共享对象中存储的最终结果 final_df = data_namespace.df print(final_df)
内容的提问来源于stack exchange,提问作者Emil
相关产品推荐
相关产品推荐

