共享numpy数组时的python多处理

共享numpy数组时的python多处理,python,arrays,numpy,python-multiprocessing,Python,Arrays,Numpy,Python Multiprocessing,我想通过利用多处理部分更改大型numpy数组中的值 也就是说,我想最终得到[[100100100],[100100100] 但是下面的代码是错误的,它说“RuntimeError:SynchronizedArray对象只应该通过继承在进程之间共享” 我该怎么办?谢谢 将numpy导入为np 导入多处理 从多处理导入RawArray,Array def change_阵列(阵列,i,j): X_np=np.frombuffer(array.get_obj(),dtype=np.float64)。重

我想通过利用多处理部分更改大型numpy数组中的值

也就是说,我想最终得到[[100100100],[100100100]

但是下面的代码是错误的,它说“RuntimeError:SynchronizedArray对象只应该通过继承在进程之间共享”

我该怎么办?谢谢

将numpy导入为np
导入多处理
从多处理导入RawArray,Array
def change_阵列(阵列,i,j):
X_np=np.frombuffer(array.get_obj(),dtype=np.float64)。重塑(2,3)
X_np[i,j]=100
打印(np.frombuffer(array.get_obj()))
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
X_形状=(2,3)
data=np.array([[1.1,2.2,3.3],[4.4,5.5,6.6])
X=数组('d',X_形[0]*X_形[1])
#将X包装为numpy数组,以便我们可以轻松地处理其数据。
X_np=np.frombuffer(X.get_obj())。重塑(X_形状)
#将数据复制到我们的共享阵列。
np.copyto(X_np,数据)
池=多处理。池(进程=3)
结果=[]
对于范围(2)中的i:
对于范围(3)内的j:
result.append(pool.apply_async(更改_数组,(X,i,j)))
result=[r.get()表示结果中的r]
pool.close()
pool.join()
打印(np.frombuffer(X.get_obj())。重塑(2,3))

多重处理中最重要的规则。如果可能,您不希望修改子流程中的共享对象。您希望您的工人计划是:

def change_array(i, j):
    value = ..... whatever value goes here
    return i, j, value

然后,您的主进程将读取返回的值
i,j,value
,并将数组元素设置为正确的值。

您需要进行两项更改:

  • 使用带有锁定(实际上是默认值)的
    多处理.Array
    实例,而不是“普通”的
    数组
  • 不要将数组实例作为参数传递给辅助函数。相反,应该使用数组作为全局值初始化池中的每个处理器
  • 印刷品:

    [100.    2.2   3.3   4.4   5.5   6.6]
    [100.  100.    3.3   4.4   5.5   6.6]
    [100.  100.  100.    4.4   5.5   6.6]
    [100.  100.  100.  100.    5.5   6.6]
    [100.  100.  100.  100.  100.    6.6]
    [100. 100. 100. 100. 100. 100.]
    [[100. 100. 100.]
     [100. 100. 100.]]
    
    更新

    由于在这种情况下,
    data
    数组中更改的值不依赖于该数组中的现有值,因此函数
    change\u array
    无需访问该数组,相反,它可以按照Frank Yellin的建议,返回要用新值更改的索引元组。但我确实想向您展示,在函数确实需要访问/修改数组的情况下,如何传递数组。但是,在本例中,您只需要以下代码(我做了一些简化):

    或:


    谢谢你的回复。我不知道它是否快。实际上,我的应用程序中的数组形状是18000*36000,我需要分别按数组[I][j]=值来更改它们。但是速度非常慢,大约需要30多个小时。因此,我不知道获取数组[I][j]的操作是否很慢?这在这里是有效的,因为在本例中,
    change\u array
    甚至不需要访问数组,因为所设置的值完全独立于数组中当前的任何值(或I和j)。但是,如果问题需要查看数组值来计算返回值,该怎么办?您尚未指定如何解决OP遇到的原始问题,即
    change\u array
    如何访问数组实例。我同意此处发布的另一个答案(@booboo),即如果您确实需要共享数组,请使用
    多处理.array
    。但我的经验是,在共享数据越少的情况下,多处理效果越好。如果每个worker都可以获得计算其结果所需的少量数据,并且可以独立于所有其他worker进行操作,那么您的代码将更易于理解和调试。您需要使用Pool的
    初始值设定项来传递共享数组。非常感谢,这就是我想要解决的问题!
    
    [100.    2.2   3.3   4.4   5.5   6.6]
    [100.  100.    3.3   4.4   5.5   6.6]
    [100.  100.  100.    4.4   5.5   6.6]
    [100.  100.  100.  100.    5.5   6.6]
    [100.  100.  100.  100.  100.    6.6]
    [100. 100. 100. 100. 100. 100.]
    [[100. 100. 100.]
     [100. 100. 100.]]
    
    import numpy as np
    import multiprocessing
    
    
    def change_array(i, j):
        return i, j, 100
    
    if __name__ == '__main__':
        data = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]])
        with multiprocessing.Pool(processes=3) as pool:
            result = [pool.apply_async(change_array, (i, j)) for i in range(2) for j in range(3)]
            for r in result:
                i, j, value = r.get()
                data[i, j] = value
            print(data)
    
    import numpy as np
    import multiprocessing
    import itertools
    
    
    def change_array(t):
        i, j = t
        return i, j, 100
    
    if __name__ == '__main__':
        data = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]])
        with multiprocessing.Pool(processes=3) as pool:
            for i, j, value in pool.map(change_array, itertools.product(range(2), range(3))):
                data[i, j] = value
            print(data)