从两个非标准化光谱中创建复合光谱

时间:2012-12-12 18:26:20

标签: python scipy

在Python中,我试图规范化两个数组,然后取它们重叠的区域的平均值来创建一个新的复合数组。

要做到这一点,我想我必须:

  1. 找到重叠区域,
  2. 插入重叠的y值,
  3. 迭代以找到最佳拟合的归一化常数,然后
  4. 将这些碎片粘贴在一起以形成我的新曲线
  5. 使用一些半随机值,这是看起来像:

    enter image description here

    此代码适用于y值不太远的小数据集,但是当Y1和Y2之间存在数量级时,Python会崩溃(显然是由于迭代)。这是代码:

    X1o = [x for x in X1 if x > X2[0]]
    X2o = [x for x in X2 if x < X1[-1]]
    Y1o = [y for y in Y1[(len(Y1)-len(X1o)):]]
    Y2o = [y for y in Y2[:len(X2o)]]
    Y2o = list(interp(X1o,X2o,Y2o))
    
    c = abs(min(Y1o)-max(Y2o))
    Y2test = [y2+c for y2 in Y2o]
    Y2s = []
    d = 0.01*min(Y2test)
    while min(Y2test) < max(Y1o):
      Y2test = [y+d for y in Y2test]
      Y2s.append(Y2test)
      plot(X1o,Y2test,c='k',alpha=0.5)
    
    idx = min(map(lambda i: (u.squaredError(Y1o, i), i, Y2s.index(i)), Y2s))[-1]         
    Yavg = [(y1+y2)/2 for y1,y2 in zip(Y1o,Y2s[idx])]
    diff = Y2s[idx][0]-Y2o[0]
    
    X = [x for x in X1 if x < X2[0]] + X1o + [x for x in X2 if x > X1[-1]]
    Y = [y for x,y in zip(X1,Y1) if x < X2[0]] + Yavg + [y+diff for x,y in zip(X2,Y2) if x > X1[-1]]
    

    我真的需要使用具有数千个数据点的恒星光谱以及y值之间的分布达到20个数量级。

    任何建议都将不胜感激!

1 个答案:

答案 0 :(得分:1)

您的代码将从numpy和使用较少的python列表中受益匪浅,这些列表效率很低,特别是您的行Y2s.append(Y2test)。当你的while周期过长时,你只会附加一个非常长的列表,这个列表很慢且效率很低。

话虽如此,代码的瓶颈是最小化。你现在正在使用python列表做暴力。使用scipy.optimize函数之一可以大大受益。

以下是我要做的一些广泛的建议:

  1. 找到两个光谱的x坐标极值,插值到常见x值的网格。
  2. 使用scipy.optimize.fmin的风格为您进行最小化并计算最佳标准化。
  3. 将标准化光谱的部分内插到公共网格
  4. 这是一些带有fmin的示例代码(未经测试):

    import numpy as np
    import scipy.optimize as opt
    
    # y1 = interpolated values for one of the spectra
    # y2 = interpolated values for the other spectra, normalise this one 
    
    def errfunc(p, a1, a2):
        return np.sum(a1 - a2 * p)
    
    p0 = 1.  # initial guess
    norm_factor = opt.fmin(errfunc, p0, args=(y1, y2))
    

    这应该给你最合适的norm_factor