我在numpy数组中有参数集,我将其输入到多处理队列中,但是当它们在worker中接收时它们会出现乱码。这是我的代码来说明我的问题和问题。
import numpy as np
from multiprocessing import Process, Queue
NUMBER_OF_PROCESSES = 2
def worker(input, output):
for args in iter(input.get, 'STOP'):
print('Worker receives: ' + repr(args))
id, par = args
# simulate a complex task, and return result
result = par['A'] * par['B']
output.put((id, result))
# Define parameters to process
parameters = np.array([
(1.0, 2.0),
(3.0, 3.0)], dtype=[('A', 'd'), ('B', 'd')])
# Create queues
task_queue = Queue()
done_queue = Queue()
# Submit tasks
for id, par in enumerate(parameters):
obj = ('id_' + str(id), par)
print('Submitting task: ' + repr(obj))
task_queue.put(obj)
# Start worker processes
for i in range(NUMBER_OF_PROCESSES):
Process(target=worker, args=(task_queue, done_queue)).start()
# Get unordered results
results = {}
for i in range(len(parameters)):
id, result = done_queue.get()
results[id] = result
# Tell child processes to stop
for i in range(NUMBER_OF_PROCESSES):
task_queue.put('STOP')
print('results: ' + str(results))
在64位CentOS计算机上使用numpy 1.4.1和Python 2.6.6,我的输出是:
Submitting task: ('id_0', (1.0, 2.0))
Submitting task: ('id_1', (3.0, 3.0))
Worker receives: ('id_0', (2.07827093387802e-316, 6.9204740511333381e-310))
Worker receives: ('id_1', (0.0, 1.8834810076011668e-316))
results: {'id_0': 0.0, 'id_1': 0.0}
如图所示,具有numpy记录数组的元组在提交任务时状况良好,但在工作程序收到参数时出现乱码,结果不正确。我在multiprocessing
documentation中读到“代理方法的参数是可选择的”。据我所知,numpy数组是完全可以选择的:
>>> import pickle
>>> for par in parameters:
... print(pickle.loads(pickle.dumps(par)))
...
(1.0, 2.0)
(3.0, 3.0)
我的问题是为什么工人没有正确接收参数?如何以其他方式将一行numpy记录数组传递给worker?
答案 0 :(得分:1)
numpy数组应该是pickle-able(我认为)但是在这里你实际上正在处理numpy.void实例,我不确定为什么,似乎不是可以发现的。
如果你这样做:
for par in parameters:
print(type(par))
print pickle.loads(pickle.dumps(par))
你得到:
<type 'numpy.void'>
(-1.3918046672290164e-41, -1.3918046679677054e-41)
<type 'numpy.void'>
(-1.3918046672290164e-41, -1.3918046679677054e-41)
解决此问题的一种方法是应用parameters = parameters.reshape([-1, 1])
将(N,)数组转换为(N,1)数组。这样当你循环遍历参数时,你将得到大小为1的数组,这将有希望腌制得很好。希望有所帮助。
答案 1 :(得分:0)
我遇到了同样的问题,但我的情况与你有点不同。
最初,我在子进程中的每个循环输出一个数字,并将它们组合成numpy.dnarray。最后,我将数组传递给Queue,但是在运行p.join()之后,我的主进程无法启动。
旧代码如下所示
let
但是,我改变了另一种方法来处理像这样的问题
+
简单地说,我只是将数据拆分为较小的部分(数据,位置)并将它们传递给队列,主进程接收数据同步。 我希望它会有所帮助