提高脚本的性能(当前的使用方法)np.putmask公司)

2024-04-18 04:00:37 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我想知道有没有比这更快的方法来把两个方程应用到一个数组上。d84、slope、q\u dis、recking\u参数都是3000乘3000的浮点数组。你知道吗

# Work out the equation for over 100
depth_100 = 1 / (3.2 * np.power((9.81 * slope), 0.3) * np.power(d84, 3 * 0.3 - 1) * np.power(q_dis, (-2 * 0.3)))

# Work out the equation for under 100
depth_1 = 1 / (1.6 * np.power((9.81 * slope), 0.23) * np.power(d84, 3 * 0.23 - 1) * np.power(q_dis, (-2 * 0.23)))

depth_fin = np.zeros_like(slope, dtype = float)

# Use np.putmask to place the calculated values into the array based on the conditional.
np.putmask(depth_fin, recking_parameter >= 100, depth_100)
np.putmask(depth_fin, recking_parameter < 100, depth_1)

Tags: thefornp数组outslopeworkpower
3条回答

在你的题目中,你强调了np.putmask的用法,但实际上大部分时间都花在算术上。使用这些能力在计算上是昂贵的,但是您仍然可以通过避免使用临时数组来提高运行时间。可以使用就地运算符(如@davidmm的答案),也可以使用^{}模块,例如:

import numexpr

depth_100 = '1 / (3.2 * (9.81 * slope)**0.3 * d84**-0.1 * q_dis**-0.6)'
depth_1 = '1 / (1.6 * (9.81 * slope)**0.23 * d84**-0.31 * q_dis**-0.46)'
depth_fin = 'where(recking_parameter < 100, '+depth_1+', '+depth_100+')'
depth_fin = numexpr.evaluate(depth_fin)

numexpr的好处是它还将使用多核。在我在双核上的测试中,它的速度大约是原始代码的4倍,但是根据您拥有的CPU,可能会获得更大的加速比。你知道吗

通过预先计算9.81*slope数组并用empty_like调用切换zeros_like调用,您可以获得约14%的改进(我已经压缩了这里的代码,使其适合页面):

slope_pre = 9.81 * slope
depth_100 = 1 / (3.2 * slope_pre**0.3 * d84**-0.1 * q_dis**-0.6)
depth_1 = 1 / (1.6 * slope_pre**0.23 * d84**-0.31 * q_dis**-0.46)
depth_fin = np.empty_like(slope)
np.putmask(depth_fin, recking_parameter >= 100, depth_100)
np.putmask(depth_fin, recking_parameter < 100, depth_1)

编辑:

另一种选择是使用Numbajit编译器进行研究,以尝试获得已编译的解决方案。诚然,我已经尝试过这一点,虽然还没走多远,但从Numba code slower than pure python这样的问题可以清楚地看出,在这样简单的计算中,有可能获得较大的加速。你知道吗

如果您不能依赖于numexpr,如moarningsun所示,您可以就地进行计算。例如:

pre_slope = 9.81 * slope
depth_100 = 1 / (3.2 * pre_slope**0.3 * d84**-0.1 * q_dis**-0.6)

正在制作一个pre_slope**0.3的临时副本,另一个d84**-0.1的临时副本,依此类推,然后为每个操作创建一个全新的副本(并根据需要丢弃)。这是一个很大的内存需求。你知道吗

可以避免:

depth_100 = d841**0.1
depth_100 *= q_dis**0.6
depth_100 /= pre_slope**0.3
depth_100 *= 1/3.2    # Note that multiplying is faster than dividing.

现在我需要更少的临时拷贝。对于depth1,如果您不需要保存所有其他数组,则可以使它变得更好:

d84 **=0.31
q_dis **=0.46
pre_slope **= 0.23

depth_1 = d84
depth_1 *= q_dis
depth_1 /= pre_slope
depth_1 *= 1/1.6

相关问题 更多 >