必须有一种更快的方法。
这里有很多事情要做,但打开包装相当简单。
这是相关的python代码(来自scipy import *)
for i in arange(len(wav)):
result[i] = sum(laser_flux * exp(-(wav[i] - laser_wav)**2) )
有一堆数组。
是的,在指数范围内,我正在逐个(逐个元素)平方标量值和laser_wav数组之间的差异。
一切都按预期工作(包括慢慢地)任何可以帮助我消除这个for循环的帮助将非常感激!
答案 0 :(得分: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)
当然,您可以将其简化为一个声明:
result = np.sum(laser_flux[:,np.newaxis] *
np.exp(-(wav[np.newaxis,:]-laser_wav[:,np.newaxis])**2),axis=0)
编辑:
正如对问题的评论中所指出的,你可以利用线性代数风格乘法定义中固有的“乘法和”。然后变成:
result = np.dot(laser_flux,
np.exp(-(wav[np.newaxis,:] - laser_wav[:,np.newaxis])**2))
答案 1 :(得分:2)
我是Python新手,所以这可能不是Python中最优秀的 ,但我会对Perl,Scheme等使用相同的技术。
def func(x):
delta = x - laser_wav
return sum(laser_flux * exp(-delta * delta))
result = map(func, wav)
答案 2 :(得分:1)
如果原始性能存在问题,您可能会受益于重写以利用多个核心(如果您拥有它们)。
from multiprocessing import Pool
p = Pool(5) # about the number of cores you have
def f(i):
delta = wav[i] - laser_wav
return sum(laser_flux * exp(-delta*delta) )
result = p.map(f, arange(len(wav)) )
答案 3 :(得分:0)
首先,将变量本身乘以使用**
幂运算符似乎稍快一些:
~$ python -m timeit -n 100000 -v "x = 4.1; x * x"
raw times: 0.0904 0.0513 0.0493
100000 loops, best of 3: 0.493 usec per loop
~$ python -m timeit -n 100000 -v "x = 4.1; x**2"
raw times: 0.101 0.147 0.118
100000 loops, best of 3: 1.01 usec per loop