2016-05-01 8 views
1

Super-User,Averaging Geodaten in 2D mit Pandas

ich einen Multi-Index Datenrahmen haben, die wie folgt aussieht:

             DATA 
DATETIME PLATFORM OBTYPE LONGITUDE LATITUDE PRESSURE 
2014-12-01 GPSRO ba  164.87 -16.22 0.2086 -1.080487 
          -99.87  51.67 433.9650 9.404006 
          -99.84  51.66 447.1593 8.621209 
          -99.82  51.65 460.5582 9.060276 
          -99.78  51.63 474.2856 4.033578 
          -99.75  51.62 488.2451 -3.564176 
          -99.72  51.61 502.6438 2.418914 
          -99.71  51.60 517.6590 9.504872 
          -99.68  51.59 533.0165 2.074352 
          -99.63  51.57 548.5572 1.692488 
          -99.61  51.56 564.5204 1.287064 
          -99.58  51.55 581.1121 2.060976 
...               ... 
          -98.81  51.25 885.3300 1.078527 
          -98.79  51.24 911.0555 -6.613088 
          -98.66  51.20 936.2419 4.369489 
          -98.61  51.18 962.0027 4.806168 
          -98.60  51.17 989.4301 -9.383631 

Die LATITUDE Spalte Werte von -90 bis +90 Die LONGITUDE Spalte hat Werte von 0 bis 360 die DATA-Spalte ist der beobachtete Wert in der beobachteten Breiten- und Längen

ich einen neuen Datenrahmen erstellen möge, die einen 1-Grad von 1-dEG-Box Mittelwert der DATA Th enthält Der neue DataFrame sieht ungefähr so ​​aus:

so weiter und so fort.

Was ist der beste und effizienteste Weg, dies in Pandas zu tun?

Dank

+0

Es ist nicht ganz klar, wie Sie neue Werte für 'LONGITUDE'- und' LATITUDE'-Spalten erhalten haben. Was ist der Algorithmus? – MaxU

+0

Es sind nur Daten. Es kann von überall her kommen. GPS-Standort, z. –

Antwort

1

Sie müssen ein paar Schritte zu tun, dass:

  1. Ihre Bins erstellen, hier ich die np.floor Funktion verwenden, weil es das tut, was Sie wollen, und hält die Dinge einfach. Hat auch den Vorteil, vektorisiert zu werden, also sollte die Leistung anständig und stabil sein.
  2. Aggregieren Sie über diese Behälter, indem Sie den Durchschnitt nehmen. Dafür hat pandas die nette groupby Funktion (docs und more on the subject). Hier

ist das, was ich tun würde (Disclaimer: Ich habe es nicht getestet haben, so dass es möglicherweise ein paar Tweaks müssen):

import numpy as np 

no_index_df = df.reset_index() 
no_index_df['LONGITUDE'] = no_index_df['LONGITUDE'].apply(lambda x: [e for e in range(0, 361, longitude_bin) if e <= x][-1]) 
no_index_df['LATITUDE'] = no_index_df['LATITUDE'].apply(lambda x: [e for e in range(-90, 91, latitude_bin) if e <= x][-1]) 

avg_data = no_index_data.groupby(
    ['DATETIME', 'PLATFORM', 'OBTYPE', 'LONGITUDE', 'LATITUDE', 'PRESSURE'] 
).mean() 

Das einzige Problem dieser Methode ist, dass Sie mehrere haben könnte Zeilen für ein gleiches (longitude, latitude) Paar, wegen der Aggregation über 'PRESSURE'. Sie könnten es aus der groupby Liste herausholen und es würde auch gemittelt werden.

EDIT: Ich habe Schritt 1 (Erstellen der Bins) geändert, damit Sie jedes Intervall verwenden können.

+0

Das funktioniert. Das Binning, das Sie ausführen, schneidet jedoch einfach die Breitengrade ab. Ich möchte mit verschiedenen Binning-Intervallen testen. 1,2,5 Grad-Behälter. Um die Druckaggregation los zu werden, nehme ich an, man könnte die Druckkolonne ganz einfach fallen lassen, da alle Druckstufen für einen Behälter angesammelt werden. –

+0

Ich habe die Antwort bearbeitet, damit Sie eine beliebige Bin-Breite verwenden können – ursan

+0

Die Bearbeitung ist für den Längengrad fehlgeschlagen. Ein IndexError taucht auf: 'IndexError: Listenindex außerhalb des Bereichs ' –