帮我消除python中的for循环

0 python for-loop

必须有一种更快的方法来做到这一点.

这里有很多东西,但打开包装相当简单.

这是相关的python代码(来自scipy import*)

for i in arange(len(wav)):
    result[i] = sum(laser_flux * exp(-(wav[i] - laser_wav)**2) )
Run Code Online (Sandbox Code Playgroud)

有一堆数组.

  • 结果 - 长度数组(wav)
  • laser_flux - 长度数组(激光)
  • wav - 长度数组(wav)
  • laser_wav - 长度数组(激光)

是的,在指数范围内,我正在逐个(逐个元素)平方标量值和laser_wav数组之间的差异.

一切都按预期工作(包括缓慢)任何帮助,你可以给我消除这个for循环将非常感谢!

Tim*_*omb 13

您将要使用Numpy数组(如果您还没有)来存储数据.然后,您可以利用阵列广播np.newaxis.对于每个值wav,您将要计算该值与每个值之间的差异laser_wav.这表明你需要一个二维数组,其中两个维度是wav维度和laser维度.

在下面的示例中,我将选择第一个索引作为laser索引,第二个索引作为wav索引.使用示例数据,这将变为:

import numpy as np

LASER_LEN  = 5
WAV_LEN    = 10
laser_flux = np.arange(LASER_LEN)
wav        = np.arange(WAV_LEN)
laser_wav  = np.array(LASER_LEN)

# Tile wav into LASER_LEN rows and tile laser_wav into WAV_LEN columns
diff    = wav[np.newaxis,:] - laser_wav[:,np.newaxis]
exp_arg = -diff ** 2
sum_arg = laser_flux[:,np.newaxis] * np.exp(exp_arg)

# Now, the resulting array sum_arg should be of size (LASER_LEN,WAV_LEN)
# Since your original sum was along each element of laser_flux/laser_wav, 
# you'll need to sum along the first axis.
result = np.sum(sum_arg, axis=0)
Run Code Online (Sandbox Code Playgroud)

当然,您可以将其简化为单个语句:

result = np.sum(laser_flux[:,np.newaxis] * 
                np.exp(-(wav[np.newaxis,:]-laser_wav[:,np.newaxis])**2),axis=0)
Run Code Online (Sandbox Code Playgroud)

编辑:

正如对问题的评论中所指出的,您可以利用线性代数风格乘法定义中固有的"乘法和".然后变成:

result = np.dot(laser_flux, 
    np.exp(-(wav[np.newaxis,:] - laser_wav[:,np.newaxis])**2))
Run Code Online (Sandbox Code Playgroud)

  • 这绝对是真的 - 当我在我的一个应用程序中进行这种类型的更改时,我注意到了一个巨大的加速. (2认同)