Building a Pandas dataframe using multiprocessing leads errors

问题描述 投票:0回答:1

我正在尝试使用一个接受一些参数并返回部分数据帧的函数来构建一个大数据帧。我有一长串文档要解析和提取将进入大数据框的相关信息,我正在尝试使用

multiprocessing.Pool
来使过程更快。

我的代码是这样的:

    from multiprocessing import *
    from settings import *
    
    server_url = settings.SERVER_URL_UAT
    username =   settings.USERNAME
    password =   settings.PASSWORD
    
    def wrapped_visit_detail(args): 
        
        global server_url
        global username
        global password
        
        # visit_detail return a dataframe after consuming args
    
        return visit_detail(server_url, args, username, password) 
    
    # Trying to pass a list of arguments to wapped_visit_detail
    
    visits_url = [doc1, doc2, doc3, doc4]
    
    df = pd.DataFrame()
    pool = Pool(cpu_count())
    df = pd.concat( [ df,
                      pool.map( wrapped_visit_detail,
                                visits_url
                                )
                      ],
                    ignore_index = True
                    )

当我运行这个时,我得到了这个错误

multiprocessing.pool.MaybeEncodingError: Error sending result: '<multiprocessing.pool.ExceptionWithTraceback object at 0x7f2c88a43208>'. Reason: 'TypeError("can't pickle _thread._local objects",)'

编辑

为了说明我的问题,我创建了这个简单的图形

这非常慢,而且根本不可扩展

我希望让代码不是串行的,而是尽可能并行化

谢谢大家到目前为止的精彩评论,是的,我使用共享变量作为这个函数的参数,它可以拉取文件并提取个人数据帧,这似乎确实不是我的问题

我怀疑我打电话的方式有问题

pool.map()

真的很欢迎任何提示

python pandas parallel-processing python-multiprocessing multiprocess
1个回答
2
投票

你自己可能已经意识到,在 Python 解释器及其子进程之间实际上没有可能的“共享”。没有共享,只有

__main__
原始的绝对独立和“断开连接”的副本,(在 Windows 中是完整的,自上而下的)Python 解释器的状态完整副本,及其所有内部变量,模块等。副本的任何更改都不会传播回
__main__
或其他地方。再一次,如果您尝试从 ~ +100k 单独预制的
“部分数据帧”
组合 “大数据帧”,您将获得非常低的性能。

部分生产者的延迟屏蔽加上 headbanging 到 RAM 分配成本中失去优势,甚至可能需要将内存 I/O 变得更糟很多倍,陷入物理/虚拟内存交换速度慢 10,000 倍的陷阱,因为内存容量不再能够保存所有数据——事后尝试时可能会发生

pd.concat( _a_HUGE_in_RAM_store_first_LIST_of_ALL_100k_plus_partial_DFs_, ... )

除非你测试 Stack Overflow 赞助商的知识幽默感和其他人的耐心 )
不行反模式。


Q:
“任何提示...”

A :
不管这个有多简单,在这里,由于 Python 解释的、进程到进程的通信限制

(未处理的EXC记者说):

multiprocessing.
           pool.MaybeEncodingError:

Error sending result:
'<multiprocessing.pool.ExceptionWithTraceback object at 0x7f2c88a43208>'.

Reason:
'TypeError("can't pickle _thread._local objects",)'

所以,
我们到了。 Python 解释器必须使用类似“pickle”的 SER/DES,每当它尝试从一个进程发送/接收单个数据时(典型情况下发送启动参数时的

__main__
,或发送远程结果时的工作进程' 对象返回
__main__
) to another.

没关系,只要 SER/DES 序列化是可能的(这里不是这种情况)

选项:

  • 最好避免任何和所有对象传递(对象容易出现 SER/DES 失败)
  • 如果痴迷于通过它们,请尝试一些功能更强大的 SER/DES 编码器,用
    pickle
    替换默认的
    import dill as pickle
    已经救了我很多次(但不是在所有情况下,见上文)
  • 设计更好的解决问题的策略,不依赖于错误假设的“共享”-在更多(完全独立的)子流程中使用 Pandas 数据框,这些子流程不能也不会访问“相同”的数据框,但它们在本地-其独立副本(重新阅读有关子进程独立性和内存空间分离的更多信息)

注意事项:
教科书 SLOC-s 在教科书大小的示例中很好,但在实际用例中是非常昂贵的性能反模式,在生产级代码执行中更多。

提示:

如果性能是目标
生成独立的基于文件的结果并在之后加入它们。 “大数据帧” “部分数据帧” 的组合代表了罪恶的混合,这会导致许多性能反模式问题,SER/DES-

pickle
的失败只是一个,一个小的(可见肉眼)

决定(以及与做出决定相关的成本)在任何情况下都在您身上。

您可能想进一步阅读有关如何提高性能的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.