问题描述
直到今天,我在Python 2.7上都使用以下代码将许多PNG图片与matplotlib
并行创建。今天,我尝试在Python 3.8上移动所有内容,而我无法适应的部分涉及使用multiprocessing
完成的并行化。
这个想法是,我有一个脚本,该脚本需要从数据文件的不同时间步生成具有相似设置的多个图像。由于可以对绘图例程进行参数设置,因此我将在10个时间步的块上执行该例程,以分配给不同任务,以加快处理速度。
这是脚本的相关部分,鉴于其长度,我将不粘贴。
from multiprocessing import Pool
from functools import partial
def main():
# arguments to be passed to the plotting functions
# contain data and @R_910_4045@ion about the plot
args = dict(m=m,x=x,y=y,ax=ax,winds_10m=winds_10m,mslp=mslp,....)
# chunks of timesteps
dates = chunks(time,10)
# partial version of the function plot_files(),see underneath
plot_files_param = partial(plot_files,**args)
p = Pool(8)
p.map(plot_files_param,dates)
def plot_files(dates,**args):
first = True
for date in dates:
#loop over dates,retrieve data from args,e.g. args['mslp'] and do the plotting
if __name__ == "__main__":
import time
start_time = time.time()
main()
elapsed_time=time.time()-start_time
print_message("script took " + time.strftime("%H:%M:%s",time.gmtime(elapsed_time)))
这曾经在Python 2.7上可以正常工作,但是现在我收到了这个错误
Traceback (most recent call last):
File "plot_winds10m.py",line 135,in <module>
main()
File "plot_winds10m.py",line 79,in main
p.map(plot_files_param,dates)
File "lib/python3.8/multiprocessing/pool.py",line 364,in map
return self._map_async(func,iterable,mapstar,chunksize).get()
File "lib/python3.8/multiprocessing/pool.py",line 771,in get
raise self._value
File "lib/python3.8/multiprocessing/pool.py",line 537,in _handle_tasks
put(task)
File "lib/python3.8/multiprocessing/connection.py",line 206,in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "lib/python3.8/multiprocessing/reduction.py",line 51,in dumps
cls(buf,protocol).dump(obj)
TypeError: cannot pickle '_thread.lock' object
除了Python版本和软件包版本以外,唯一更改的是系统。我正在MacOS而不是Linux上进行测试,但这不会有太大的不同,尤其是因为它们都在conda环境中运行。
有人知道如何解决此问题吗?
(这是github存储库https://github.com/guidocioni/icon_forecasts/blob/master/plotting/plot_winds10m.py的链接)
解决方法
我想出了一个问题,以防万一有人拼命地来到这里寻求答案。
问题是我使用metpy.unit_array
进行的某些转换会生成pint
数组,由于某种原因,该数组不是pickable
。然后,当我在args
函数的partial
中传递此数组时,出现了错误。
尝试使用.convert_units()
进行转换或仅从数据中提取数组部分(使用.values
或.magnitude
)确保我只传递了{{1} }数组或numpy
且这些对象是可选取的。