我想通过python多处理填充数组。
例如,我想使用“ for range(2)中的x”通过两个处理器填充数组。
第一个处理器是i = 1
第二个处理器是i = 2
但是,它显示“ TypeError:'int'对象不可迭代”
代码可能类似于:
import numpy as np
import multiprocessing
from multiprocessing import Process, Queue, Array
import ctypes
def Calculation(i):
for j in range(0,2):
Ans[i][j] = Para_1[i][j]*Para_2[i][j]/Para_3[i][j]
if __name__ == "__main__":
Ans = np.zeros((2,2))
Para_1 = [[5,4],[1,2]]
Para_2 = [[1,2],[3,4]]
Para_3 = [[4,4],[2,5]]
processes = [Process(target=Calculation, args=(x)) for x in range(2)]
for p in processes:
p.start()
for p in processes:
p.join()
print(Ans)
答案 0 :(得分:1)
Process的“ args”关键字参数必须是可迭代的,由TypeError异常提示。
在您的代码中,您在方括号中提供了x(与给x相同),这是范围函数提供的整数
(x) == x
看来,您想要做的是为元组提供一个值。这要求您添加一个逗号以指示它是一个具有一个值的元组,而不是方括号内的单个值。根据查尔斯的答案:
processes = [Process(target=Calculation, args=(x,)) for x in range(2)]
您同样可以提供一个列表,该列表也是可迭代的。然后,您将不需要逗号,因为列表使用方括号,因此具有一项的列表不会被解释为方括号中的项目。
processes = [Process(target=Calculation, args=[x]) for x in range(2)]
接下来是您问题的实际答案...
多重处理将您的函数分为多个独立的进程,每个进程都有各自的内存,因此您无法在子进程的主进程中编辑数组。
您可以使用线程执行此操作,在这种情况下,您的线程使用相同的内存,因此可以正常工作。如果您不想进行太多更改,可以使用multiprocessing.dummy库,该库在后端使用线程而不是子进程。只需更改您的导入行
from multiprocessing.dummy import Process, Queue, Array
但是,这通常没有任何好处。由于存在GIL,除非您花费大量时间等待IO缓慢之类的东西,否则python中的线程无法提供加速。如果要使用多重处理,则应重构代码以使并行函数返回其计算出的值。
其他一些注意事项:
您不需要先导入多处理程序,然后再从中导入特定功能,只需第二个导入行就足够了。
您在这里不使用ctypes,因此除非这只是一个代码段,否则也无需导入它。
在外部范围内具有函数引用变量是不好的做法。您应该将Ans,Para_1,Para_2和Para_3作为参数传递
import numpy as np
from multiprocessing.dummy import Process
def Calculation(i):
for j in range(0,2):
Ans[i][j] = Para_1[i][j]*Para_2[i][j]/Para_3[i][j]
if __name__ == "__main__":
Ans = np.zeros((2,2))
Para_1 = [[5,4],[1,2]]
Para_2 = [[1,2],[3,4]]
Para_3 = [[4,4],[2,5]]
processes = [Process(target=Calculation, args=(x,)) for x in range(2)]
for p in processes:
p.start()
for p in processes:
p.join()
print(Ans)
返回
[[1.25 2. ]
[1.5 1.6 ]]