web-dev-qa-db-fra.com

`ValueError: Une valeur dans x_new est au-dessus de la plage d'interpolation. '- quelles autres raisons que de ne pas augmenter les valeurs?

Je reçois cette erreur dans la fonction scipy interp1d. Normalement, cette erreur serait générée si le x n'augmentait pas de façon monotone.

import scipy.interpolate as spi
def refine(coarsex,coarsey,step):
    finex = np.arange(min(coarsex),max(coarsex)+step,step)
    intfunc = spi.interp1d(coarsex, coarsey,axis=0)
    finey = intfunc(finex)
    return finex, finey

for num, tfile in enumerate(files):
    tfile = tfile.dropna(how='any')
    x = np.array(tfile['col1'])
    y = np.array(tfile['col2'])
    finex, finey = refine(x,y,0.01)

Le code est correct, car il a fonctionné avec succès sur 6 fichiers de données et a jeté l'erreur pour le 7ème. Il doit donc y avoir un problème avec les données. Mais pour autant que je sache, les données augmentent tout le long. Je suis désolé de ne pas avoir fourni d'exemple, car je ne suis pas en mesure de reproduire l'erreur sur un exemple.

Il y a deux choses qui pourraient m'aider:

  1. Quelques remue-méninges - si les données augmentent effectivement de façon monotone, quoi d'autre pourrait produire cette erreur? Un autre indice, concernant les décimales, pourrait être dans cette question , mais je pense que ma solution (le min et le max de x) est suffisamment robuste pour l'éviter. Ou non?
  2. Est-il possible (comment?) De renvoyer la valeur de x_new et son index lors du lancement du ValueError: A value in x_new is above the interpolation range. Afin que je puisse voir où se trouve le problème?

[~ # ~] mise à jour [~ # ~]

Ainsi, le problème est que, pour une raison quelconque, max(finex) est plus grande que max(coarsex) (l'un est .x39 et l'autre est .x4). J'espérais que l'arrondi des valeurs originales à 2 chiffres significatifs résoudrait le problème, mais il ne l'a pas fait, il affiche moins de chiffres mais compte toujours avec les caractères non affichés. Que puis-je faire à ce sujet?

8
durbachit

Si vous exécutez Scipy v. 0.17.0 ou plus récent, alors vous pouvez passez fill_value='extrapolate' À spi.interp1d , et il extrapolera pour s'adapter à ces valeurs de votre mensonge en dehors de la plage d'interpolation. Définissez donc votre fonction d'interpolation comme suit:

intfunc = spi.interp1d(coarsex, coarsey,axis=0, fill_value="extrapolate")

Soyez averti, cependant!

Selon l'apparence de vos données et le type d'interpolation que vous effectuez, les valeurs extrapolées peuvent être erronées. Cela est particulièrement vrai si vous avez des données bruyantes ou non monotones. Dans votre cas, vous pourriez être d'accord car votre valeur x_new est seulement légèrement au-delà de votre plage d'interpolation.

Voici une démonstration simple de la façon dont cette fonctionnalité peut fonctionner correctement, mais donne également des résultats erronés.

import scipy.interpolate as spi
import numpy as np

x = np.linspace(0,1,100)
y = x + np.random.randint(-1,1,100)/100
x_new = np.linspace(0,1.1,100)
intfunc = spi.interp1d(x,y,fill_value="extrapolate")
y_interp = intfunc(x_new)

import matplotlib.pyplot as plt
plt.plot(x_new,y_interp,'r', label='interp/extrap')
plt.plot(x,y, 'b--', label='data')
plt.legend()
plt.show()

enter image description here

La partie interpolée (en rouge) a donc bien fonctionné, mais la partie extrapolée ne parvient clairement pas à suivre la tendance par ailleurs linéaire de ces données en raison du bruit. Ayez donc une certaine compréhension de vos données et procédez avec prudence.

22
saintsfan342000

Un test rapide de votre finex calc montre qu'il peut (toujours?) Entrer dans la région d'extrapolation.

In [124]: coarsex=np.random.Rand(100)
In [125]: max(coarsex)
Out[125]: 0.97393109991816473
In [126]: step=.01;finex=np.arange(min(coarsex), max(coarsex)+step, step);(max(
     ...: finex),max(coarsex))
Out[126]: (0.98273730602114795, 0.97393109991816473)
In [127]: step=.001;finex=np.arange(min(coarsex), max(coarsex)+step, step);(max
     ...: (finex),max(coarsex))
Out[127]: (0.97473730602114794, 0.97393109991816473)

Encore une fois, c'est un test rapide et il peut manquer une étape ou une valeur critique.

1
hpaulj