Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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-为2D屏蔽数组并行化Python循环?_Python_Loops_Numpy_Parallel Processing_Mask - Fatal编程技术网

Python-为2D屏蔽数组并行化Python循环?

Python-为2D屏蔽数组并行化Python循环?,python,loops,numpy,parallel-processing,mask,Python,Loops,Numpy,Parallel Processing,Mask,这可能是一个常见的问题,但是如何在Python中并行化这个循环呢 for i in range(0,Nx.shape[2]): for j in range(0,Nx.shape[2]): NI=Nx[:,:,i]; NJ=Nx[:,:,j] Ku[i,j] = (NI[mask!=True]*NJ[mask!=True]).sum() 所以我的问题是:并行化代码的最简单方法是什么 ---------- EDIT LATER----------------

这可能是一个常见的问题,但是如何在Python中并行化这个循环呢

for i in range(0,Nx.shape[2]):
  for j in range(0,Nx.shape[2]):
    NI=Nx[:,:,i]; NJ=Nx[:,:,j]
    Ku[i,j] = (NI[mask!=True]*NJ[mask!=True]).sum()
所以我的问题是:并行化代码的最简单方法是什么

         ---------- EDIT LATER------------------
数据示例

import random
import numpy as np
import numpy.ma as ma
from numpy import unravel_index    

#my input
Nx = np.random.rand(5,5,5)  

#mask creation
mask_positions = zip(*np.where((Nx[:,:,0] < 0.4)))
mask_array_positions = np.asarray(mask_positions)
i, j = mask_array_positions.T
mask = np.zeros(Nx[:,:,0].shape, bool)
mask[i,j] = True
随机导入
将numpy作为np导入
将numpy.ma导入为ma
从numpy导入展开索引
#我的意见
Nx=np.rand.rand(5,5,5)
#面具创作
掩码位置=zip(*np.where((Nx[:,:,0]<0.4)))
掩码数组位置=np.asarray(掩码数组位置)
i、 j=掩模阵列位置。T
掩码=np.zero(Nx[:,:,0]。形状,布尔)
掩码[i,j]=真

我想通过并行计算Ku。我的目标是使用Ku数组来解决线性问题,因此我必须将掩码值分开(表示数组的近一半)

我认为您想要“矢量化”,使用
numpy
术语,而不是以多进程方式并行化

您的计算本质上是一个点(矩阵)积。将
掩码
应用于整个阵列一次,以获得二维阵列,
NIJ
。它的形状将是
(N,5)
,其中
N
~mask
True
值的数目。然后它只是一个
(5,N)
数组,用
(N,5)
“点”了一个
(N,5)
-即,在
N
维度上求和,留下一个
(5,5)
数组

NIJ = Nx[~mask,:]
Ku = np.dot(NIJ.T,NIJ)
在快速测试中,它匹配双循环产生的
Ku
。根据用于
np.dot
的底层库,可能会有一些多核计算,但这通常不是
numpy
用户的优先问题


应用大型布尔
掩码
是这些计算中最耗时的部分,包括矢量化和迭代版本

对于具有400000个真值的
掩码
,比较以下两个索引时间:

In [195]: timeit (NI[:400,:1000],NJ[:400,:1000])
100000 loops, best of 3: 4.87 us per loop
In [196]: timeit (NI[mask],NJ[mask])
10 loops, best of 3: 98.8 ms per loop
使用基本(切片)索引选择相同数量的项目比使用
掩码的高级索引快几个数量级


np.dot(NI[mask],NJ[mask])
代替
(NI[mask]*NJ[mask]).sum()
只节省了几毫秒。

我想你想要“矢量化”,使用
numpy
术语,而不是以多进程方式并行化

您的计算本质上是一个点(矩阵)积。将
掩码
应用于整个阵列一次,以获得二维阵列,
NIJ
。它的形状将是
(N,5)
,其中
N
~mask
True
值的数目。然后它只是一个
(5,N)
数组,用
(N,5)
“点”了一个
(N,5)
-即,在
N
维度上求和,留下一个
(5,5)
数组

NIJ = Nx[~mask,:]
Ku = np.dot(NIJ.T,NIJ)
在快速测试中,它匹配双循环产生的
Ku
。根据用于
np.dot
的底层库,可能会有一些多核计算,但这通常不是
numpy
用户的优先问题


应用大型布尔
掩码
是这些计算中最耗时的部分,包括矢量化和迭代版本

对于具有400000个真值的
掩码
,比较以下两个索引时间:

In [195]: timeit (NI[:400,:1000],NJ[:400,:1000])
100000 loops, best of 3: 4.87 us per loop
In [196]: timeit (NI[mask],NJ[mask])
10 loops, best of 3: 98.8 ms per loop
使用基本(切片)索引选择相同数量的项目比使用
掩码的高级索引快几个数量级


np.dot(NI[mask],NJ[mask])
代替
(NI[mask]*NJ[mask]).sum()
只节省了几毫秒。

我想把@hpaulj的优秀答案(顺便说一下,对问题的分析也很棒)扩展到大型矩阵

手术

Ku = np.dot(NIJ.T,NIJ)
可以用

Ku = np.einsum('ij,ik->jk', NIJ, NIJ)
还应注意,如果numpy未编译为使用BLAS,则
np.dot

对于形状为
(1250711,50)
的测试矩阵
NIJ
,我用
dot
方法得到
54.9s
,而
einsum
1.67s
中得到。在我的系统上,numpy是使用BLAS支持编译的

备注
np.einsum
并不总是优于
np.dot
,当您比较以下任何一项时,我的系统就会发现这种情况

Nx = np.random.rand(1400,1528,20).astype(np.float16)
Nx = np.random.rand(1400,1528,20).astype(np.float32)

(甚至是一种
np.float64
)的数据类型。

我想扩展@hpaulj对于大型矩阵的优秀答案(顺便说一下,对问题的分析也很棒)

手术

Ku = np.dot(NIJ.T,NIJ)
可以用

Ku = np.einsum('ij,ik->jk', NIJ, NIJ)
还应注意,如果numpy未编译为使用BLAS,则
np.dot

对于形状为
(1250711,50)
的测试矩阵
NIJ
,我用
dot
方法得到
54.9s
,而
einsum
1.67s
中得到。在我的系统上,numpy是使用BLAS支持编译的

备注
np.einsum
并不总是优于
np.dot
,当您比较以下任何一项时,我的系统就会发现这种情况

Nx = np.random.rand(1400,1528,20).astype(np.float16)
Nx = np.random.rand(1400,1528,20).astype(np.float32)

(甚至是
np.float64
)的数据类型。

请提供一些示例数据和预期输出。顺便说一下,在实现“@ HPAULJ的优秀答案”之外,您可能需要考虑,您在5行中编写的“掩码”等同于编写“代码>掩码=Nx[:,,0 ] < 0.4 < /代码>。请提供一些示例数据和预期输出。顺便说一下,在实现@ HPAULJ的优秀答案之外,您可能需要考虑,您在5行中制作的掩码等同于只写“代码>掩码=NX [:,,0 ] ]。<0.4
。我必须在大量的数组上执行此操作,然后我使用“np.linalg.solve”来解决使用这些数组的系统,我想加速它…@user3601754您尝试过此代码吗?很快。如果需要说服力,请执行一些时间比较。我知道你的问题的历史,在尝试多进程之前,你一定要考虑这个解决方案。