Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将numpy数组放入多处理队列的困难_Python_Numpy_Multiprocessing_Pickle - Fatal编程技术网

Python 将numpy数组放入多处理队列的困难

Python 将numpy数组放入多处理队列的困难,python,numpy,multiprocessing,pickle,Python,Numpy,Multiprocessing,Pickle,我在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('Work

我在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记录数组的元组在提交任务时处于良好状态,但在工作者接收到参数时会出现混乱,并且结果不正确。我在文章中读到“代理方法的参数是可选择的”。据我所知,numpy阵列是完全可以挑选的:

>>> import pickle
>>> for par in parameters:
...     print(pickle.loads(pickle.dumps(par)))
...     
(1.0, 2.0)
(3.0, 3.0)

我的问题是为什么worker中没有正确接收参数?否则,我如何才能将一行numpy记录数组传递给工作进程?

numpy数组应该是可pickle的(我认为),但这里实际处理的是numpy.void实例,我不知道为什么,它们似乎不可pickle

如果您这样做:

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)

(-1.3918046672290164e-41,-1.3918046679677054e-41)
(-1.3918046672290164e-41,-1.3918046679677054e-41)

解决这一问题的一种方法是应用
parameters=parameters。重塑([-1,1])
使(N,)数组成为(N,1)数组。这样,当您在参数上循环时,您将得到大小为1的数组,希望它可以很好地进行pickle。希望对你有所帮助。

我遇到过与你相同的问题,但我的情况与你略有不同

最初,我在子流程中的每个循环中输出一个数字,并将它们组合到numpy.dnarray中。最后,我将数组传递给队列,但在运行p.join()之后,我的主进程无法启动

旧代码如下所示

# subprocess
for i in range(n):
    array[i] = data[i]
queue.put(array)
# main process
queue.get()
然而,我改变了另一种方式来处理这样的问题

# subprocess
for i in range(n):
    queue.put((i, data[i]))
# main process
for i in range(n):
    while queue.empty():
        i, data = queue.get()
        array[i] = data
简单地说,我只是将数据分成更小的部分(数据、位置)并将它们传递给队列,然后主进程接收数据同步。
我希望这会有所帮助

看起来您的问题是一个bug,已在本次提交中修复