Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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_Arrays_Numpy_Mask_Slice - Fatal编程技术网

Python 对“部分”的有效数学运算;稀疏的;numpy阵列

Python 对“部分”的有效数学运算;稀疏的;numpy阵列,python,arrays,numpy,mask,slice,Python,Arrays,Numpy,Mask,Slice,在博士论文的模拟中,我面临以下挑战: 我需要优化以下代码: repelling_forces = repelling_force_prefactor * np.exp(-(height_r_t/potential_steepness)) 在这个代码段中,“height\u r\u t”是一个真正的Numpy数组,“potential\u陡峭度”是一个标量Rejecting_force_prefactor'也是一个Numpy数组,它大部分为零,但在预先计算的位置有一个,在运行时不会改变(即掩码)

在博士论文的模拟中,我面临以下挑战:

我需要优化以下代码:

repelling_forces = repelling_force_prefactor * np.exp(-(height_r_t/potential_steepness))
在这个代码段中,“height\u r\u t”是一个真正的Numpy数组,“potential\u陡峭度”是一个标量Rejecting_force_prefactor'也是一个Numpy数组,它大部分为零,但在预先计算的位置有一个,在运行时不会改变(即掩码)。 显然,该代码效率低下,因为只计算“排斥力”和“预因子”为非零的位置处的指数函数更有意义

问题是我如何以最有效的方式做到这一点

到目前为止,我唯一的想法是使用“排斥力预因子”将切片定义为“高度”,并对这些切片应用“np.exp”。然而,根据我的经验,切片速度很慢(不确定这是否通常是正确的),解决方案似乎很尴尬

正如旁注,“排斥力预因子”中的1:0的比例大约是1/1000,我在循环中运行这个,所以效率非常重要。
(评论:我使用Cython不会有问题,因为我需要/希望在某个时候学习它……但我是新手,所以我需要一个好的指针/解释。)

切片可能比计算所有指数快得多。我建议在非零索引处预计算索引,并使用它们进行切片,而不是直接使用掩码
排斥\u force\u预因子

# before the loop
indices = np.nonzero(repelling_force_prefactor)

# inside the loop
repelling_forces = np.exp(-(height_r_t[indices]/potential_steepness))
现在,排斥力将只包含非零的结果。如果必须使用此值更新
高度
原始形状的某些数组,则可以再次使用带
索引的切片,或使用
np.put()
或类似函数


在这种情况下,使用索引列表进行切片将比使用布尔掩码进行切片更有效,因为索引列表缩短了千分之一。实际上,性能的测量当然取决于您。

切片可能比计算所有指数快得多。我建议在非零索引处预计算索引,并使用它们进行切片,而不是直接使用掩码
排斥\u force\u预因子

# before the loop
indices = np.nonzero(repelling_force_prefactor)

# inside the loop
repelling_forces = np.exp(-(height_r_t[indices]/potential_steepness))
现在,排斥力将只包含非零的结果。如果必须使用此值更新
高度
原始形状的某些数组,则可以再次使用带
索引的切片,或使用
np.put()
或类似函数


在这种情况下,使用索引列表进行切片将比使用布尔掩码进行切片更有效,因为索引列表缩短了千分之一。实际上,性能的测量当然取决于您。

屏蔽阵列的实现完全是为了您的目的

性能与Sven的答案相同:

height_r_t = np.ma.masked_where(repelling_force_prefactor == 0, height_r_t)
repelling_forces = np.ma.exp(-(height_r_t/potential_steepness))
掩蔽数组的优点是,不必对数组进行切片和扩展,数组的大小总是相同的,但是numpy自动知道不计算掩蔽数组的exp


此外,您还可以对具有不同掩码的数组求和,得到的数组具有掩码的交点。

掩码数组的实现完全符合您的目的

性能与Sven的答案相同:

height_r_t = np.ma.masked_where(repelling_force_prefactor == 0, height_r_t)
repelling_forces = np.ma.exp(-(height_r_t/potential_steepness))
掩蔽数组的优点是,不必对数组进行切片和扩展,数组的大小总是相同的,但是numpy自动知道不计算掩蔽数组的exp


此外,您还可以对具有不同遮罩的数组求和,得到的数组具有遮罩的交点。

+1比我快。我只想补充一点,这样做有几个选项,如果代码的这一部分是瓶颈,最好的做法是对每个选项进行基准测试。一般来说,我发现切片速度非常快,尤其是当比率为1/1000时。我只想补充一点,这样做有几个选项,如果代码的这一部分是瓶颈,最好的做法是对每个选项进行基准测试。总的来说,我发现切片速度非常快,尤其是当比率为1/1000时。这是一个非常简洁的解决方案,因为它是一个优雅的解决方案。另一个问题——也许你在最后一句话中提到了这一点。我可以用这种方法对矩阵的不同部分进行运算吗;i、 例如:height_part1=height(mask1)height_part2=height(mask2),然后如果我对height_part1或height_part2进行数学运算,比如height_part1=operation1(height_part1),它们会反映在height中吗?是的,mask是一个简单的布尔数组,存储在masked_数组的
.mask
属性中。创建屏蔽数组时,可以指定copy=False,以便将操作反映到原始数组中。但是最好的策略取决于应用程序的细节。这是一个非常简洁的解决方案,因为它非常优雅。另一个问题——也许你在最后一句话中提到了这一点。我可以用这种方法对矩阵的不同部分进行运算吗;i、 例如:height_part1=height(mask1)height_part2=height(mask2),然后如果我对height_part1或height_part2进行数学运算,比如height_part1=operation1(height_part1),它们会反映在height中吗?是的,mask是一个简单的布尔数组,存储在masked_数组的
.mask
属性中。创建屏蔽数组时,可以指定copy=False,以便将操作反映到原始数组中。但最佳策略取决于应用程序的细节。