Vergleich/Lookup von zwei DataFrames

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
newPythonista
User
Beiträge: 2
Registriert: Donnerstag 27. August 2015, 09:24

Hallo zusammen,

ich hoffe ich verletze nicht irgendwelche Postingregeln, ich mache das zum ersten Mal.
ich habe ein kleines kompliziertes Problem mit zwei Pandas Dataframes, woran ich jetzt schon eine Weile tüftle und Internetrecherche leider keinen Erfolg brachte. Vermutlich ist die Lösung recht klar, aber ich komme einfach nicht darauf.
Ich benutze Python 2.7.6.2 und Pandas 0.13.0 (updates nicht möglich).

Also meine Dataframes sehen wie folgt aus (sorry, ich habe die Formatierung nicht hinbekommen):

DF1:

Index A B C
2014-07-01 01:00:00 0 0 0
2014-07-01 01:10:00 382 450 107
2014-07-01 01:20:00 311 330 205
2014-07-01 01:30:00 239 312 551
2014-07-01 01:40:00 403 354 451
2014-07-01 01:50:00 287 395 259
2014-07-01 02:00:00 447 592 539
2014-07-01 02:10:00 375 696 451
2014-07-01 02:20:00 317 337 368
… … … …

DF2:

Index Y Z
0 0.60 0.0
1 1.05 0.0
2 1.50 0.0
3 2.04 0.0
4 2.50 0.0
5 3.04 32.9
6 3.53 83.1
7 3.99 153.4
8 4.48 235.9
9 5.01 335.2
10 5.51 492.0
11 6.01 625.1
12 6.52 855.3
13 7.01 1080.4
14 7.50 1342.0
15 7.99 1471.5
… … …

Was ich nun brauche ist eine Art lookup: Die Werte aus DF1 sollen mit der Spalte Z verglichen werden und der entsprechende Wert Y sowie die Datum/Uhrzeit aus DF1 ausgegeben werden. Ich habe es schon mit pandas.lookup probiert oder mit for-Schleife und einem dict. Nun ist es so, dass die Werte aber nicht genau passen. Ich brauche also noch irgendwie einen range oder eine Interpolation. Ein Beispiel: Aus DF1 in Spalte A der Wert 382 liegt in DF2 Spalte Z zwischen 337.2 und 494.0. Als Y-Wert muss also etwas zwischen 5.01 und 5.51 rauskommen und dazu Datum/Uhrzeit 2015-05-01 01:10:00. Am Ende hätte ich gerne einen neuen Dataframe3, der in etwa so aussieht (ausgedachte Werte):

Index A B C
2014-07-01 01:00:00 0 0 0
2014-07-01 01:10:00 5.3 5.4 5.7
2014-07-01 01:20:00 4.2 5.2 5.1
… … … …

Vielleicht kann man auch DF2 so interpolieren, dass in Spalte Z Integer mit Schrittweise 1 stehen? Allerdings handelt es sich um einen sigmoidalen Verlauf.
Ich hoffe ich konnte mein Problem klarmachen. Für schnelle Hilfe wäre ich sehr dankbar!

newPythonista
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Es sieht so aus, als ob die Werte der Z-Spalte aufsteigend sortiert sind, wenn das immer so ist, dann hilft Dir
numpy.searchsorted
a fool with a tool is still a fool, www.magben.de, YouTube
newPythonista
User
Beiträge: 2
Registriert: Donnerstag 27. August 2015, 09:24

Danke MagBen, ich hatte die numpy-Funktionen gar nicht mehr alle im Blick. np.searchsorted geht leider nicht so gut, da die Werte nicht immer aufsteigend sind, sondern am Anfang und Ende plateauhaft verlaufen können (also mehrere Nullen z.B.). Aber das brachte mich darauf, es mit np.interp zu versuchen. Meine Lösung:

xp = DF2['Z'].values
fp = DF2['Y'].values

DF3 = DF1.apply(lambda x: np.interp(x, xp, fp), axis=1)

Ich muss die Werte noch eingehender prüfen, aber auf den ersten Blick sieht es passend aus.
Antworten