2010-11-19 59 views
2

我有以下函數,我希望從表中插入一個指定的值。訣竅在於,對數表定義爲對數對數,使得對數對數中的點之間的直線是真正指數的。因此我不能真正使用任何典型的scipy內插例程。numpy magic清理函數

因此,這裏是我有:

PSD = np.array([[5.0, 0.001], 
       [25.0, 0.03], 
       [30.0, 0.03], 
       [89.0, 0.321], 
       [90.0, 1.0], 
       [260.0, 1.0], 
       [261.0, 0.03], 
       [359.0, 0.03], 
       [360.0, 0.5], 
       [520.0, 0.5], 
       [540.0, 0.25], 
       [780.0, 0.25], 
       [781.0, 0.03], 
       [2000.0, 0.03]]) 

def W_F(freq): 
    ''' 
    A line connecting two points in a log-log plot are exponential 
    ''' 
    w_f = [] 
    for f in freq: 
     index = np.searchsorted(PSD[:,0], f) 
     if index <= 0: 
      w_f.append(PSD[:,1][0]) 
     elif index + 1>= PSD.shape[0]: 
      w_f.append(PSD[:,1][-1]) 
     x0 = PSD[:,0][index-1] 
     F0 = PSD[:,1][index-1] 
     x1 = PSD[:,0][index] 
     F1 = PSD[:,1][index] 
     w_f.append(F0*(f/x0)**(math.log(F1/F0)/math.log(x1/x0))) 
    return np.array(w_f) 

我正在尋找一個更好,更清潔,「numpy的十歲上下」的方式來實現走的是剛拿本

+1

'for freq = in f:' - 僅僅是一個轉錄錯字或者你的代碼不工作?另外,你不應該在倒數第二行而不是f使用freq嗎? – 2010-11-19 23:01:01

+0

是的,功能不正確。應該閱讀: – user90855 2010-11-21 13:37:10

+0

我已更正了錯誤 – user90855 2010-11-21 13:39:31

回答

3

最簡單的方法的PSD對數,然後使用SciPy的插補功能:

logPSD = numpy.log(PSD) 
logW_F = scipy.interpolate.interp1d(logPSD[:,0], logPSD[:,1]) 
W_F = numpy.exp(logW_F(numpy.log(f))) 

這將拋出一個錯誤對於超出範圍的值。爲了避免錯誤,你可以

  • 通行證bounds_error=Falseinterp1d()功能,見the documentation

  • 在PSD的開始和結尾處添加一個條目,其中包含一個非常小且非常大的x值以捕獲所有可能的值。

作爲替代使用interp1d(),有可能vectorise你的代碼,但我只會做是有原因的。

+0

正是我在找的東西。我認爲最後一行的日誌(f)應該改爲numpy.log(f) – user90855 2010-11-21 13:54:55

+0

是的,你是對的。沒有測試代碼:) – 2010-11-21 14:15:10