Problem mit 2D-interpolation in SciPy, nicht-rechteckiges-raster
Ich habe versucht, zu verwenden scipy.interpolieren.bisplrep() und scipy.interpolieren.interp2d() zu finden interpolants für Daten auf meinem (218x135) 2D-sphärisch-polar-Gitter. Dieser E-pass 2D-arrays, X und Y die kartesischen Positionen von meiner grid-Knoten. Ich erhalte Fehler wie den folgenden (für linear-interp. mit interp2d):
"Warnung: Keine mehr Knoten Hinzugefügt werden können, da die zusätzlichen Knoten Zusammenfallen würde
mit einem alten. Wahrscheinlich Ursache: zu kleine oder zu große Gewicht
um eine ungenaue Daten zeigen. (fp>s)
kx,ky=1,1 nx,ny=4,5 m=29430 fp=1390609718.902140 s=0.000000"
Bekomme ich ein ähnliches Ergebnis für bivariate splines mit dem default-Wert der smoothing-parameter s usw. Meine Daten glatt sind. Ich angehängt habe meinen code unten in den Fall mache ich offensichtlich etwas falsch.
Irgendwelche Ideen?
Danke!
Kyle
class Field(object):
Nr = 0
Ntheta = 0
grid = np.array([])
def __init__(self, Nr, Ntheta, f):
self.Nr = Nr
self.Ntheta = Ntheta
self.grid = np.empty([Nr, Ntheta])
for i in range(Nr):
for j in range(Ntheta):
self.grid[i,j] = f[i*Ntheta + j]
def calculate_lines(filename):
ri,ti,r,t,Br,Bt,Bphi,Bmag = np.loadtxt(filename, skiprows=3,\
usecols=(1,2,3,4,5,6,7,9), unpack=True)
Nr = int(max(ri)) + 1
Ntheta = int(max(ti)) + 1
### Initialise coordinate grids ###
X = np.empty([Nr, Ntheta])
Y = np.empty([Nr, Ntheta])
for i in range(Nr):
for j in range(Ntheta):
indx = i*Ntheta + j
X[i,j] = r[indx]*sin(t[indx])
Y[i,j] = r[indx]*cos(t[indx])
### Initialise field objects ###
Bradial = Field(Nr=Nr, Ntheta=Ntheta, f=Br)
### Interpolate the fields ###
intp_Br = interpolate.interp2d(X, Y, Bradial.grid, kind='linear')
#rbf_0 = interpolate.Rbf(X,Y, Bradial.grid, epsilon=2)
return
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hinzugefügt 27Aug: Kyle folgte dieser bis auf eine
scipy-user-thread.
30Aug: @Kyle, es sieht aus, als ob da eine Verwechslung zwischen Cartesion X -, Y-und polar Xnew,Ynew.
Siehe "polar" in die viel zu lange Hinweise unten.
Hinweise auf 2d-interpolation, BivariateSpline vs. griddata.
scipy.interpolate.*BivariateSpline
undmatplotlib.mlab.griddata
beide nehmen 1d-arrays als Argumente:
Den Eingängen
X,Y,Z
beschreiben eine Oberfläche oder eine Wolke von Punkten im 3-Raum:X,Y
(oder Breite,Länge oder ...) Punkte in einer Ebene,und
Z
eine Oberfläche oder Gelände über.X,Y
füllen können, die meisten von dem Rechteck [Xmin .. Xmax] x [Ymin .. Ymax],oder vielleicht nur ein squiggly S oder Y drin.
Die
Z
Oberfläche kann glatt oder glatt + ein bisschen Lärm,oder gar nicht glatt, raue vulkanische Berge.
Xnew und Ynew sind in der Regel auch 1d, beschreibt ein rechteckiges raster
der |Xnew| x |Ynew| Punkte, wo Sie wollen, zu interpolieren oder Schätzung Z.
Znew = griddata(...) gibt ein 2d-array über das Netz, np.meshgrid(Xnew,Ynew):
Xnew,Ynew Punkte weit ab von der Eingabe X,Y s Zauber Probleme.
griddata
prüft:("Konvexe Hülle" wird das Gebiet innerhalb eines imaginären
Gummiband gedehnt, um die ganze X,Y-Punkte.)
griddata
funktioniert so, dass zunächst die Konstruktion einer Delaunay-triangulationder Eingang X -, Y -, dann tun
Natürlicher Nachbar
interpolation. Dieser ist robust und ziemlich schnell.
BivariateSpline, obwohl, kann extrapolieren,
Generierung von wilden Schaukeln ohne Warnung.
Darüber hinaus werden alle *Spline-Routinen in Fitpack
sind sehr empfindlich auf parameter Glättung S.
Dierckx ' s Buch (die Bücher.google-isbn 019853440X p. 89) sagt, dass:
wenn S zu klein ist, die spline-approximation zu Verwackeln
und nimmt zu viel Lärm (overfit);
wenn S zu groß ist der spline zu glatt
und signal verloren (underfit).
Interpolation gestreuter Daten ist schwer, Glättung nicht leicht, beides zusammen wirklich schwer.
Was sollte ein interpolator tun mit großen Löcher in XY, oder sehr laute Z ?
("Wenn Sie wollen, um es zu verkaufen, sind Sie gehen zu müssen, um es zu beschreiben.")
Noch weitere Hinweise, kleingedrucktes:
1d vs 2d: Einige interpolatoren X,Y,Z entweder 1d oder 2d.
Andere nehmen 1d nur, so flatten vor der Interpolation:
Auf maskierte arrays: matplotlib behandelt Sie gut,
Plotten nur entlarvt /non-NaN Punkte.
Aber ich würde nicht Wetten, dass ein bozo-numpy/scipy Funktionen überhaupt funktionieren.
Überprüfen Sie für die interpolation außerhalb der konvexen Hülle von X,Y so:
Auf Polarkoordinaten:
X -, Y-und Xnew,Ynew, sollte sich im selben Raum,
beide Cartesion, oder beide in [rmin .. rmax] x [tmin .. tmax].
Zum plot (r, theta, z) Punkte in 3d:
Siehe auch (habe nicht versucht dies):
Zwei Tipps für die vorsichtigen Programmierer:
check für Ausreißer, oder lustige Skalierung:
check-interpolation mit einfachen Daten: