我试图优化我写的Python脚本已经两天了。使用了几个分析工具(如cProfile,line_profiler等),我将issue缩小到以下函数。
df是一个拥有3列和1000000+行的numpy数组(数据类型为float)。使用line_profiler,我发现每当它需要访问numpy数组时,该函数花费大部分时间。
下面两行代码会占用大部分时间:
full_length += head + df[rnd_truck, 2]
full_weight += df[rnd_truck,1]
其次是这两行:
full_length = df[rnd_truck,2]
full_weight = df[rnd_truck,1]
就我所见,瓶颈是函数尝试从numpy数组中获取数字时的访问时间。
当我以MonteCarlo(df, 15., 1000.)形式运行该函数时,在i7 3.40GhZ 64位Windows机器上运行1,000,000次函数调用需时37秒。在我的应用程序中,我需要运行10亿次才能保证收敛,这将使执行时间超过一小时。我尝试使用operator.add方法来替换求和行,但完全没有帮助。看起来我必须找出一种更快的方法来访问这个numpy数组。
欢迎任何想法!
df是一个拥有3列和1000000+行的numpy数组(数据类型为float)。使用line_profiler,我发现每当它需要访问numpy数组时,该函数花费大部分时间。
下面两行代码会占用大部分时间:
full_length += head + df[rnd_truck, 2]
full_weight += df[rnd_truck,1]
其次是这两行:
full_length = df[rnd_truck,2]
full_weight = df[rnd_truck,1]
就我所见,瓶颈是函数尝试从numpy数组中获取数字时的访问时间。
当我以MonteCarlo(df, 15., 1000.)形式运行该函数时,在i7 3.40GhZ 64位Windows机器上运行1,000,000次函数调用需时37秒。在我的应用程序中,我需要运行10亿次才能保证收敛,这将使执行时间超过一小时。我尝试使用operator.add方法来替换求和行,但完全没有帮助。看起来我必须找出一种更快的方法来访问这个numpy数组。
欢迎任何想法!
def MonteCarlo(df,head,span):
# Pick initial truck
rnd_truck = np.random.randint(0,len(df))
full_length = df[rnd_truck,2]
full_weight = df[rnd_truck,1]
# Loop using other random truck until the bridge is full
while 1:
rnd_truck = np.random.randint(0,len(df))
full_length += head + df[rnd_truck, 2]
if full_length > span:
break
else:
full_weight += df[rnd_truck,1]
# Return average weight per feet on the bridge
return(full_weight/span)
以下是我正在使用的df
numpy数组的一部分:
In [31] df
Out[31]:
array([[ 12. , 220.4, 108.4],
[ 11. , 220.4, 106.2],
[ 11. , 220.3, 113.6],
...,
[ 4. , 13.9, 36.8],
[ 3. , 13.7, 33.9],
[ 3. , 13.7, 10.7]])