2012-12-12 98 views
2

在Python中,我試圖規範化兩個數組,然後取其重疊區域的平均值以創建一個新的複合數組。從兩個非標準化的光譜創建複合光譜

要做到這一點,我想我必須:

  1. 找到重疊的區域,
  2. 插值重疊的y值,
  3. 迭代通過找到最適合的歸一化常數,然後
  4. 碎片粘貼在一起,形成我的新曲線

有一些半隨機值,這裏是塔牛逼的樣子:

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項目。

任何建議將不勝感激!

+0

*「顯然是由於迭代」*什麼讓你說這個? – dmckee

+0

如果您想要更高效的代碼,您可以先擺脫列表推導並使用numpy數組操作。 – tiago

+0

@tiago我剛開始看看Numpy。特別是你認爲可能會有幫助嗎? –

回答

1

您的代碼將從numpy中受益匪淺,並使用更少的python列表,這些列表效率低下,特別是您的行Y2s.append(Y2test)。當你的while週期太長時,你只會追加到一個很長的列表,這是一個緩慢而低效率的列表。

這就是說,你的代碼的瓶頸是最小化。您目前正在用python列表進行強力操作。使用scipy.optimize函數之一可以大大受益。

這裏是什麼,我會做一些廣泛的建議:

  1. 查找x座標極端的兩個譜,既插常見的x值的網格。
  2. 使用scipy.optimize.fmin的風格爲您做最小化並計算最佳規範化。歸一化譜的一個共同格

  • 插值部分下面是一些示例代碼(非測試)與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

  • +0

    是的!這很好,儘管我把'errfunc()'改成'np.sum(abs(a1 - (a2 + p)))'來找到最佳擬合的歸一化偏移量,而不是歸一化因子。非常感謝! –