如何通过并行计算为pandas DataFrame批量创建新列
并行生成DataFrame列的实现方法
完全可以通过multiprocessing、joblib等并行库实现需求,核心原则是不要在子进程中直接操作同一个DataFrame——多进程内存空间是隔离的,跨进程修改全局对象不仅不会生效,还会带来极高的序列化开销。正确的思路是把每个变量的生成分拆为独立子任务,子任务仅返回「列名+生成的数组」,最后在主进程统一组装为DataFrame即可。
方案1:使用joblib(推荐,适配数据科学场景)
joblib对numpy数组这类科学计算对象做了序列化优化,并行传输开销比原生multiprocessing更低,代码写法也更简洁,是这类场景的首选。
import numpy as np import pandas as pd from joblib import Parallel, delayed class Variable: def __init__(self, name: str, size: int): self.name = name self.size = size def generate(self) -> np.ndarray: # 替换为你实际的高复杂度生成逻辑 return np.random.uniform(size=self.size) # 独立子任务:仅负责生成单个变量的数据,返回列名和对应数组 def _gen_col(var: Variable): return var.name, var.generate() if __name__ == "__main__": # 初始化变量 a, b, c = Variable("a", 10), Variable("b", 10), Variable("c", 10) var_list = [a, b, c] # n_jobs=-1表示调用全部CPU核心,可根据需求手动指定核心数 col_results = Parallel(n_jobs=-1)( delayed(_gen_col)(v) for v in var_list ) # 主进程一次性组装DataFrame df = pd.DataFrame(dict(col_results)) print(df)
方案2:使用原生multiprocessing(无额外依赖)
如果不想安装第三方库,可以直接用Python标准库自带的multiprocessing实现,逻辑和joblib版本完全一致:
import numpy as np import pandas as pd from multiprocessing import Pool class Variable: def __init__(self, name: str, size: int): self.name = name self.size = size def generate(self) -> np.ndarray: return np.random.uniform(size=self.size) def _gen_col(var: Variable): return var.name, var.generate() if __name__ == "__main__": a, b, c = Variable("a", 10), Variable("b", 10), Variable("c", 10) var_list = [a, b, c] # 默认创建和CPU核心数相等的进程 with Pool() as pool: col_results = pool.map(_gen_col, var_list) df = pd.DataFrame(dict(col_results)) print(df)
注意事项
- 跨平台兼容:Windows系统、以及macOS/Linux使用
spawn进程启动模式时,所有多进程逻辑必须放在if __name__ == "__main__":代码块下,否则会出现无限递归启动进程的报错。 - 随机数问题:如果生成逻辑依赖随机数,需要给每个子任务单独设置独立的随机种子,避免不同进程生成重复的随机序列。
- 性能判断:如果单个变量的生成逻辑本身耗时极短(比如示例里的单次均匀分布随机数生成),进程创建、跨进程数据传输的开销会远大于并行带来的收益,最终速度反而比串行慢。只有当单变量生成计算量足够大时,并行才会有明显的提速效果。
- 避免共享对象:不要把DataFrame、大字典这类全局对象作为参数传给子任务,会大幅增加序列化传输开销,子任务只需要接收必要的参数、返回生成的列数据即可。
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

