2010-11-19 3 views
2

J'ai la fonction suivante dans laquelle je souhaite interpoler à partir d'une table à une valeur spécifiée. L'astuce est que la table est définie dans un sens log-log de sorte que les lignes droites entre les points dans log-log sont vraiment exponentielles. Ainsi, je ne peux pas vraiment utiliser l'une des routines d'interpolation scipy typiques.magie numpy pour la fonction de nettoyage

Alors, voici ce que j'ai:

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) 

Je suis à la recherche d'un meilleur, plus propre, « numpy-ish » façon de mettre en œuvre cette

+1

'pour freq = in f:' - est juste une faute de transcription ou votre code ne fonctionne-t-il pas? De même, ne devriez-vous pas utiliser freq dans l'avant-dernière ligne au lieu de f? –

+0

Oui, la fonction est incorrecte. Devrait se lire: – user90855

+0

J'ai corrigé l'erreur – user90855

Répondre

3

La meilleure façon d'aller est de prendre juste la logarithme de PSD puis utiliser les fonctions d'interpolation SciPy:

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

Ce jetteront une erreur pour les valeurs hors des limites. Pour éviter l'erreur, vous pouvez

  • passe bounds_error=False à la fonction interp1d(), voir the documentation.

  • Ajoutez une entrée au début et à la fin de PSD avec une valeur x très petite et très grande pour capturer toutes les valeurs possibles.

Comme alternative à l'utilisation interp1d(), il est possible de vectoriser votre code, mais je ne le faire pour une raison.

+0

Juste ce que je cherchais. Je pense que le log (f) sur la dernière ligne devrait être changé en numpy.log (f) – user90855

+0

Ouim vous avez raison. N'a pas testé le code :) –