Fehler nach Interpolation

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Hallo,

erhalte einen Fehler nach Interpolation.

Dateiformat spec besteht aus Zeilen die "frames" bzw. Propagationsschritte darstellen und die Spalteneinträge enthalten Energiewerte über der Frequenz.
Diese möchte ich interpolieren auf eine andere Achse.
a = spec[1,:] = scipy.interpolate.interp1d(x, spec[1,:], 'linear')
Fehlermeldung tritt auf :

TypeError: float() argument must be a string or a number, not 'interp1d'
and in Variablen-Browser:
a=<scipy.interpolate.interpolate.interp1d object at 0x7f12943f8cc0>
A ist also kein Array, wie kann das zu number/float konvertiert werden?

Grüße,

proxquad
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

interp1d liefert eine "Funktion", der man die x-Werte übergeben muß, damit die y-Werte berechnet werden.
Ein Beispiel zur Anwendung steht auch in der Dokumentation, was immer der erste Blick sein sollte, wenn man eine Funktion neu benutzt.
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

x = np.linspace(3e8/v_max, 3e8/v_min, np.size(spec, 1))
a_1 = spec[1,:] = scipy.interpolate.interp1d(x, spec[1,:], 'linear')
newarr = a_1(x)
print(newarr)
änder auch nichts.

Kannst du das bitte genauer erläutern?

Fehlermeldung erscheint:
a_1 = spec[1,:] = scipy.interpolate.interp1d(x, spec[1,:], 'linear')
TypeError: float() argument must be a string or a number, not 'interp1d'
Also ist der Schritt ja schon fehlerbehaftet.
Was ist daran falsch?
Benutzeravatar
__blackjack__
User
Beiträge: 13927
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@proxquad: Was soll denn der ``spec[1,:] = scipy.interpolate.interp1d(x, spec[1,:], 'linear')``-Teil Deiner Meinung nach machen/bewirken?
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Ach stimmt!
x = np.linspace(3e8/v_max, 3e8/v_min, np.size(spec, 1))
a_1 = scipy.interpolate.interp1d(x, spec[1,:], 'linear')
newarr = a_1(x)
... funktioniert.

Nun ist das Ziel aber das Ausgangsdatenset (ein 2-D-Array mit Zeileneinträgen als "Frames" und Spalteneinträgen als Energie (abh. von Frequenz)) für alle Zeilen zu interpolieren ausgeführt werden.
Deshalb das spec[1, :] zu Beginn. (wollte für erste Zeile probieren)
x = np.linspace(3e8/v_max, 3e8/v_min, np.size(spec, 1))
scale = 1/(x*x)
n = 100
for i in range(1, n):
spec[i,:] = scipy.interpolate.interp1d(x, spec[i,:]*scale, 'linear')
newarr = spec[i,:](x)
Fehlermeldung:
IndentationError: expected an indented block
Was ist der Fehler in der vorgehensweiße? Zeile für Zeile soll ja interpoliert werden.
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

... und wie fügt man die interpolierten Zeilen wieder zu einem 2-D Array zusammen?

Also Ausgangsarray, wobei E_ für Energiewerte steht und F_ für Frames:

***E_1 E_2 E_3 ...
F_1
F_2
F_3
...

Jetzt sollen alle Energiewerte eines Frames auf eine neue Achse interpoliert werden.

Damit:
***E_1' E_2' E_3' ...
F_1
F_2
F_3
...
Benutzeravatar
sparrow
User
Beiträge: 4506
Registriert: Freitag 17. April 2009, 10:28

@proxquad: Zu der Fehlermeldung: In Python sind Einrückungen fundamental, weil dadurch Blöcke gekennzeichnet werden. Der Interpreter weist dich hier darauf hin, dass in deinem Code ein eingerückter Block erwartet wird aber nicht kommt.
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

@sparrow.

Ja mit Einrückung funktioniert es. Ist auch übersichtlicher so.
x = np.linspace(3e8/v_max, 3e8/v_min, np.size(spec, 1))
scale = 1/(x*x)
n = 100
for i in range(1, n):
a_i[i,:] = scipy.interpolate.interp1d(x, spec[i,:], 'linear')
newarr = a_i[i,:](x)
Wir lässt sich nun jede Zeile vom Augangsarray interpolieren?
So funktioniert nicht.

Error:
newarr = a_i[i,:](x)
TypeError: 'interp1d' object is not subscriptable
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

@proxquad: da ist doch wieder der selbe Fehler vom Anfang drin, dass Du versuchst ein interp1d-Objekt einem Array-Vektor zuzuweisen.
Arbeite zuerst ein Grundlagentutorial durch, dann das Tutorial von numpy, und dann sollten die grundlegenden Fragen beantwortet sein.
Es macht übrigens keinen Sinn, an den Stützstellen x das Polynom auszuwerten.

Wenn Du dann soweit alles gelernt hast, kannst Du das in einer Zeile lösen:

Code: Alles auswählen

interpolated_spec = scipy.interpolate.interp1d(x, spec, 'linear', axis=0)(interpolated_x)
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

@sirius

Im Tutorial der Scipy interpolation1d:
from scipy.interpolate import interp1d
import numpy as np

xs = np.arange(10)
ys = 2*xs + 1

interp_func = interp1d(xs, ys)

newarr = interp_func(np.arange(2.1, 3, 0.1))

print(newarr)
... wird dem interp1d-object ebenfalls ein vektor zugewiesen mit:
interp_func = interp1d(xs, ys)
So habe ich das auch gemacht, nur in eine for-scheife stecken wollen.

Das von dir genannten Grundlagen muss ich mir vermutlich wirklich angeignen, aber dennoch habe ich eine Frage zu der Code-line:
interpolated_spec = scipy.interpolate.interp1d(x, spec, 'linear', axis=0)(interpolated_x)
ist interpolated_x
np.linspace(3e8/v_max, 3e8/v_min, np.size(spec, 1))
?
Falls ja, was ist x?

und wie wiso werden damit alle zeilen von spec interpoliert?
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Das mußt Du ja beantworten können, was x ist und was interpolating_x ist, also was die Stützstellen sind und auf welches Raster Du interpolieren willst. Bisher ist das bei Dir das selbe, was, wie ich schon schrieb, keinen Sinn ergibt.
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Die Ausgangslage ein Datensatz mit Zeilen als Frames und Spalten als Energiewerte. "spec"

Datensatz enthält 101 Zeilen (Frames) , also liegen 101 Spektren vor.:

***E_1 E_2 E_3 ...
F_1
F_2
F_3
...

Diese Spektren sollen auf einer anderen Achse geplottet werden (später mit imshow), dabei müssen die Energiewerte skaliert werden.

***E_1' E_2' E_3' ...
F_1
F_2
F_3
v = np.linspace(v_min, v_max, np.size(spec,1)) #Frequenzachse
l = 3e8/v #Wellenlängenachse (
interpolated_x = np.linspace(3e8/v_max, 3e8/v_min, np.size(spec, 1))

scale = 1/(interpolated_x*interpolated_x)
n = 100
for i in range(1, n):
"[space]" interpolated_spec = scipy.interpolate.interp1d(l, spec[i,:]*scale, 'linear', axis=0)(interpolated_x)
fig2 = plt.figure()
matplotlib.pyplot.xticks(fontsize=15)
matplotlib.pyplot.yticks(fontsize=15)
bx2 = fig2.add_subplot(122)

# draw the spectrum
bx2.imshow(interpolated_spec,aspect='auto',interpolation='bicubic',cmap='jet',vmin=spec_max-db_range,vmax=spec_max,origin='lower',extent=[v_max,v_min,0,fd.distance])
bx2.set_xlabel('Wellenlänge (nm)', fontsize=20)
bx2.set_ylabel('Propagation (m)', fontsize=20)
fig2.suptitle('PM 980 XP/HP: 5cm,200nJ', fontsize=25)

Aber das interpolated_spec ist nur ein Zeilenvektor?

Wie lässt sich jede Zeile des Ausgangsdatensatzes interpolieren?
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Also wie lassen sich die einzelnen Interpolationen wieder in ein Array schreiben das plot-bar ist?
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Benutze bitte Code-Tags </> damit man den Code auch lesen kann.
Statt np.size(array, 1), benutzt man array.shape[1].
Statt einbuchstabiger Variablennamen sollte man aussagekräftigere nehmen. l ist ganz schlecht, weil es mit 1 oder I leicht zu verwechseln ist.
Dass man gar keine for-Schleife braucht, habe ich Dir schon gezeigt. Meist sind Schleifen bei numpy ein Hinweis darauf, dass man irgend etwas falsch macht.
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Code: Alles auswählen

freq = np.linspace(v_min, v_max, spec.shape[1]) #Frequenzachse über linspace da nicht gegeben - so richtig?!
well = 3e8/freq
interpolated_x = np.linspace(3e8/v_max, 3e8/v_min, spec.shape[1])

scale = 3e8/(interpolated_x*interpolated_x)
interpolated_spec = scipy.interpolate.interp1d(well, spec, 'linear', axis=0)(interpolated_x)
=> ValueError: x and y arrays must be equal in length along interpolation axis.

Problem:

Code: Alles auswählen

spec.shape
(101, 8192)
well.shape
(8192,)
Anmerkung: 101 Zeilen sind frames und 8192 Spalten sind Energiewerte. D.h.jedem Frame ist ein Spektrum zugeordnet.

Und damit ist

Code: Alles auswählen

interpolated_x.shape
(8192,)
Spektrum für alle Zeilen soll ja auf eine neue Achse interpoliert werden und über eine for schleife würde das doch über alle Zeilen interpolieren, oder?
Kannst du mir bitte nochmal erklären wie das ohne for schleife funktioniert?
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Du willst auch über axis=1 interpolieren. Das hatte ich vorhin falsch gelesen.
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Code: Alles auswählen

frames = np.linspace(0, 100,101)
freq = np.linspace(v_min, v_max, spec.shape[1]) #Frequenzachse über linspace da nicht gegeben - so richtig?!
well = 3e8/freq
interpolated_x = np.linspace(3e8/v_max, 3e8/v_min, spec.shape[1])

scale = 3e8/(interpolated_x*interpolated_x)
scale_matrix = scale*np.ones(spec.shape)
spec_scaled = scale_matrix*spec
interpolated_spec = scipy.interpolate.interp2d(frames, well, spec_scaled)(frames, interpolated_x)
wobei:

Code: Alles auswählen

frames.shape
(101,)
well.shape
(8192,)
spec_scaled.shape
(101, 8192)
interpolated_x.shape
(8192,)
führt auch nicht zum Ziel:
raise ValueError("When on a regular grid with x.size = m "
ValueError: When on a regular grid with x.size = m and y.size = n, if z.ndim == 2, then z must have shape (n, m)
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Sirius3 hat geschrieben: Donnerstag 8. Oktober 2020, 12:58 Du willst auch über axis=1 interpolieren. Das hatte ich vorhin falsch gelesen.

Code: Alles auswählen

frames = np.linspace(0, 100,101)
freq = np.linspace(v_min, v_max, spec.shape[1]) #Frequenzachse über linspace da nicht gegeben - so richtig?!
well = 3e8/freq
interpolated_x = np.linspace(3e8/v_max, 3e8/v_min, spec.shape[1])

scale = 3e8/(interpolated_x*interpolated_x)
scale_matrix = scale*np.ones(spec.shape)
spec_scaled = scale_matrix*spec
interpolated_spec = scipy.interpolate.interp1d(well, spec_scaled,  'linear', axis=1)(interpolated_x)

Code: Alles auswählen

    raise ValueError(f"x and y must have same first dimension, but "
ValueError: x and y must have same first dimension, but have shapes (8192,) and (101, 8192)
also hier eine for-schleife??
proxquad
User
Beiträge: 16
Registriert: Samstag 30. November 2019, 12:51

Ansatz über Meshgrid...

Code: Alles auswählen

frames = np.linspace(0, 100,101)
interpolated_x = np.linspace(3e8/v_max, 3e8/v_min, spec.shape[1])

Frames, Interpolated_x = np.meshgrid(frames,interpolated_x)
freq = np.linspace(v_min, v_max, spec.shape[1]) #Frequenzachse über linspace da nicht gegeben - so richtig?!
well = 3e8/freq

scale = 3e8/(interpolated_x*interpolated_x)
scale_matrix = scale*np.ones(spec.shape)
spec_scaled = scale_matrix*spec
for i in range(0,100):
    interpolated_spec1 = scipy.interpolate.interp2d(frames, well, spec_scaled)(Frames, Interpolated_x)
wobei

Code: Alles auswählen

Frames.shape
(8192, 101)
Interpolated_x.shape
(8192, 101)
frames.shape
(101,)
well.shape
(8192,)
spec_scaled.shape
(101, 8192)
führt zu:
raise ValueError("When on a regular grid with x.size = m "
ValueError: When on a regular grid with x.size = m and y.size = n, if z.ndim == 2, then z must have shape (n, m)
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Jetzt hast Du sehr viele, sehr komische Arrays eingeführt.
Beim mir funktioniert der Code

Code: Alles auswählen

frames = np.linspace(0, 100,101)
freq = np.linspace(v_min, v_max, spec.shape[1]) #Frequenzachse über linspace da nicht gegeben - so richtig?!
well = 3e8/freq
interpolated_x = np.linspace(3e8/v_max, 3e8/v_min, spec.shape[1])

scale = 3e8/(interpolated_x*interpolated_x)
scale_matrix = scale*np.ones(spec.shape)
spec_scaled = scale_matrix*spec
interpolated_spec = scipy.interpolate.interp1d(well, spec_scaled,  'linear', axis=1)(interpolated_x)
ohne Probleme.
Wie sieht die komplette Fehlermeldung inklusive Traceback aus?
`scale_matrix` ist überflüssig, es geht einfach `spec_scaled = scale * spec`
Antworten