为什么在Python中调用scipy.stats.gaussian_kde()会导致multiprocessing.queue.get()失败?

为什么在Python中调用scipy.stats.gaussian_kde()会导致multiprocessing.queue.get()失败?,python,scipy,multiprocessing,Python,Scipy,Multiprocessing,目标是并行构建多个绘图图形,然后将它们合并为一个包含子图和插图的绘图。下面是一个简化的部分版本,它只是隔离了这个问题 创建绘图图形的辅助函数和使用多处理模块的辅助函数保存在当前工作目录中的文件/模块中。多处理雇主函数是从Jupyter笔记本调用的,希望能够可视化创建的绘图 问题是调用scipy.stats.gaussian_kde()时,无法从多处理队列中检索对象;queue.get()显示一条空错误消息。当我注释掉有问题的代码并将其放在jupyter笔记本中,只使用KDE绘图数据更新绘图时,它

目标是并行构建多个绘图图形,然后将它们合并为一个包含子图和插图的绘图。下面是一个简化的部分版本,它只是隔离了这个问题

创建绘图图形的辅助函数和使用多处理模块的辅助函数保存在当前工作目录中的文件/模块中。多处理雇主函数是从Jupyter笔记本调用的,希望能够可视化创建的绘图

问题是调用scipy.stats.gaussian_kde()时,无法从多处理队列中检索对象;queue.get()显示一条空错误消息。当我注释掉有问题的代码并将其放在jupyter笔记本中,只使用KDE绘图数据更新绘图时,它工作正常。其余不依赖KDE的数据可以从队列中检索

有没有办法解决这个问题?另一方面,使用线程模块比多处理路径更快,并且不需要我将worker和employer函数保存在juytper脚本的单独文件中。然而,我仍然想了解这个问题和任何可能的补救办法。我错过了什么

多进程测试.py

        def worker_func(ticker,out_q):
            """Puts Plotly dict of figure into queue."""
            # import pandas as pd
            # import pandas_datareader.data as pdr
            # import plotly.graph_objs as go   
            # import scipy
            # import numpy as np
    
            outdict={}
            df = pdr.DataReader(ticker)
            dfc = df.Close.pct_change().dropna()

            fig = go.Figure()
            fig.add_trace(go.Histogram(
                name=ticker,
                histnorm='probability density',
                x=dfc))
    
            # calling gaussian_kde() leads to empty queue; why?
            # ~~ offending code ~~ 
            kernel = scipy.stats.gaussian_kde(dfc.values) # hangs here
            kdep = np.linspace(dfc.min(),dfc.max(),1000)

            fig.add_trace(go.Scatter(
                x=kdep,
                y=kernel.pdf(kdep)
            ))
            # ~~ end of offending code ~~ 

            outdict.update(fig.to_dict())
            out_q.put(outdict)

            out_q.close()
            out_q.join_thread()


        def mp_employer(tickers):
            """Return multiprocessed list of Plotly figure dicts."""
            # import multiprocessing

            out_q = multiprocessing.Queue()
            process_list=[]
            for item in tickers:
                p = multiprocessing.Process(name=item, target=worker_func,
                                            args=(item,out_q),daemon=True)
                p.start()
                process_list.append(p)
                print(p)
            print('pre-join qsize:',out_q.qsize())

            print('getting from queue')
            result_list=list()
            for i in range(len(tickers)):
                # get before join else queue empty
                result_list.append(out_q.get(timeout=5))
            print('got from queue')
        
            print('start join')
            for p in process_list:
                p.join()

            print('post-join qsize:',out_q.qsize())
            print('successfully retrieved from queue')

            return result_list

Jupyter笔记本脚本

from multiprocess_test import  mp_employer # in cwd
import scipy
import numpy as np
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)

if __name__ == "__main__":
    plot_figs = 'N/A'
    plot_figs = mp_employer(['FB','AAPL','MSFT'])
    
    for fig_dict in plot_figs:
        fig = go.Figure(**fig_dict)
        
#         # called gaussian_kde() here bc it caused queue.get() to hang
#         # KDE data
#         x_values=fig_dict['data'][0]['x']
#         kernel = scipy.stats.gaussian_kde(x_values)
#         kdep = np.linspace(x_values.min(),x_values.max(),1000)
#         # KDE fig
#         fig.add_trace(go.Scatter(
#             x=kdep,
#             y=kernel.pdf(kdep)
#         ))
        
        iplot(fig)