Wissenschaftliche Programmierung mit Python - für Meteorologie und Atmosphärenforschung Martin G....

38
Wissenschaftliche Programmierung mit Python - für Meteorologie und Atmosphärenforschung Martin G. Schultz Teil 4: Dateien

Transcript of Wissenschaftliche Programmierung mit Python - für Meteorologie und Atmosphärenforschung Martin G....

Wissenschaftliche Programmierung mit Python

- für Meteorologie und Atmosphärenforschung

Martin G. Schultz

Teil 4: Dateien

2

Generell folgender Ablauf:Öffnen:handle = open(filename, mode)

Lesen oder Schreiben von Daten:handle.read() handle.write()handle.readline() handle.write(s+’\n’)handle.readlines() handle.writelines()

Schließen:handle.close()

Umgang mit Dateien

wird automatisch in das richtigeUmbruchzeichen für dasBetriebssystem umgewandelt

siehe auch: http://www.tutorialspoint.com/python/python_files_io.htm

Fehlerbehandlung

3

Beim Umgang mit Dateien geht (fast) immer etwas schief. Daher:

f.closed kann benutzt werden, um zu Testen, ob eine Datei (noch) geöffnet ist.

Probier es auch mal mit „w“

Fehler sollten immer spezifiziert werden

Fehlerbehandlung (2)

4

Warum nicht:

?

5

Das with statement sorgt dafür, dass die Datei beim Verlassen des Programmblocks geschlossen wird (auch bei Fehlern)

Ein f.close() ist damit erstens unnötig und führt zweitens zu einem Fehler.

Dateien in einem Rutsch(integrierte Fehlerbehandlung mit „with“)

More info: http://effbot.org/zone/python-with-statement.htm

Das Open Statement

6

open ist der Konstruktor für das file Objekt …

f = open( filename [, mode [, buffering]] )

filename: Name der Datei, u.U. inklusive Pfad (auch bei Windows immer ″/″!)

mode:″r″ : Lesen (default) ″r+″: Lesen und Schreiben″w″: Schreiben″a″: Anhängen″b″: binärer Modus (als zweites Zeichen)

buffering:0 : unbuffered1 : line bufferedn > 1 : Puffergröße in Bytesn < 0 : system default

7

Lesen und Schreiben von Dateien

Drucke Sonderzeichen mit

Das Dateiende wird durch einen leeren Stringangezeigt. Eine leere Zeile enthält stattdessenimmer noch das „\n“ Zeichen. Daher wird contentFalse, wenn das Dateiende erreicht ist.

Lesen/Schreiben von Binärdaten (1):tofile und fromfile

8

Was geht hier schief? Wie kann man das verhindern?

Anmerkung: tofile und fromfile können sowohl für binäre als auch für ascii Dateienverwendet werden. Für ascii Dateien gibt es sep=″″ und format=″%s″.

Lesen/Schreiben von Binärdaten (2):save und load

9Bei np.save wird die Endung .npy automatisch angehängt.

numpy.save merkt sich den Typ und die Form des Arrays.

Aufgaben1. Erzeuge zwei numpy arrays mit unterschiedlichen Datentypen und

verschiedenen Größen. Schreibe beide Felder in eine Binärdatei.a) Benutze dafür numpy.saveb) Benutze dafür array.tofile

2. Nun lese beide Felder wieder aus der Datei ausa) mit numpy.loadb) mit numpy.fromfile

Tipp 1: Die Datei braucht zum Lesen für jede Teilaufgabe nur einmal geöffnet zu werden. Statt des Dateinamens kann der „handle“ an load bzw. fromfile übergeben werden.Tipp 2: numpy.fromfile kennt ein count Argument

Lesen/Schreiben beliebiger Python Objekte

11

Das pickle Modul

# pickle.dump(a, f, -1) schreibt im Binärformat

Excel-Dateien

12

1. Excel Spreadsheets (.xls): xlrd, xlwt, xlutils modules http://www.python-excel.org/

2. CSV files (.csv):csv.reader http://www.doughellmann.com/PyMOTW/csv/numpy.loadtext() numpy.genfromtext()matplotlib.mlab.csv2rec()ei

nfac

here

Han

dhab

ung

CSV-Dateien (1)

13

Beispiel:

csv2rec Lösung:

Die Datumsspalte wird automatisch in datetime Objekte umgewandelt.Anschließend kann z.B. plot(data1[′time′], data1[′DD′]) oder plot(data1.time, data1.DD)angewendet werden.data1 ist ein sogenanntes numpy.recarray.

Datei: temperature_wind_demo.csv

CSV-Dateien (2)

14

numpy.genfromtxt Lösung:

Hier wird aus der Datumsspalte ein numerischer (float64) Wert.Ansonsten ist auch data2 ein numpy.recarray.

numpy.loadtxt Lösung:

CSV-Dateien (3)

15

csv.reader Lösung:

CSV-Dateien: Analyse

16

• Alle 4 Beispiele erlauben das Einlesen der Daten in der CSV Datei• Die einzelnen Variablen können jeweils namentlich angesprochen

werden: • data1.ff oder data1[ff ]• data2[FF], data3[FF], data4[FF]

• Data1 ist ein numpy recarray, die anderen sind das nicht. Umwandlung möglich durch np.view(np.recarray)

• Data1 und data2 speichern die (float) Werte als float64, data3 und data4 als float32

• Datumsformate:• data1: datetime.datetime() Datumsstruktur (richtig erkannt)• data2: float Zahlen (734796.52083333 etc.)• data3: dto.• data4: strings (S16), keine Umwandlung

Exkurs: numpy.recarray

17

Ein recarray ist ein (numpy) array mit spezifizierten Datentypen (dtypes).Der dtype gibt Datentyp, Feldnamen und Feldgröße an.

Man kann auch „normale“ nparrays mit „records“ (also Kombinationen unterschiedlicher Datentypen) definieren:

Durch Umwandlung in ein recarray wird es möglich, die einzelnen Bestandteile eines records als Attribute anzusprechen:

r.name führt zu einem Fehler

Exkurs: Datumsformate

18

Datum und Zeit könnten locker Thema einer eigenen Vorlesung sein (verschiedene Kalender, Schaltsekunden, Lokalzeit, Sommerzeit, etc.).

Für unsere Zwecke reichen in den meisten Fällen sog. „naive“ Datums- und Zeitangaben:• der gegenwärtige gregorianische Kalender ist und war immer gültig• es gibt keine Schaltsekunden• die Interpretation einer Uhrzeit (Zeitzone) hängt vom Benutzer ab

Mit der Klasse tzinfo kann man auch eindeutige (nicht naive) Zeitangaben machen.

Python bietet verschiedene Module zum Umgang mit Daten und Zeiten:• datetime• time• calendar• dateutil

Exkurs: Datumsformate

19

datetime.timedelta wird für Zeitdifferenzen benutzt. Intern werden diese als Zahl der Tage, Sekunden und Mikrosekunden gespeichert.datetime.date speichert Datumsangaben als Tage seit dem 1.1.1 ab („proleptischer gregorianischer Kalender“).datetime.time speichert Zeitangaben zwischen 00:00:00 h und 24:00:00 h – 1 µs.datetime.datetime kombiniert Datum und Zeit.

Beispiele:

Exkurs: Datumsformate

20

Beispiele:

Montag einmal 0 und einmal 1

Zahl der Tage seit 1.1.1

timedelta

Achtung! Nicht -1:30:00 h

Achtung! Wir haben nur nach den Sekunden gefragt.

Na? Wer war das wohl?

Exkurs: Datumsformate

21

„Unix“-Zeit: Zahl der Sekunden seit dem 1.1.1970 00:00:00 h („timestamp“). Wird von time.time() zurückgegeben (s. numpy Zeitmessung)

Matplotlib-Zeit: Zahl der Tage (mit Dezimalen) seit dem 1.1.1. Es gibt in matplotlib auch epoch, das sind dann wieder Unix-Zeiten.

Beispiel:

Mehr Infos: http://www.seehuhn.de/pages/pdate

Formatieren von Datumsangaben

22

ctime() und isoformat() geben ein datetime Objekt im Format DOW MON DD hh:mm:ss YYYY bzw. YYYY-MM-DDThh:mm:ss aus (s.o.).Mit strftime(format) kann ein Datum in einem beliebigen Format ausgegeben werden. strptime(datestring, format) wandelt einen String in ein datetime Datumsobjekt um.

Beispiele:

Formatieren von Datumsangaben

23

Format

Meaning Example

%Y Year as 4-digit integer 2012

%y Year as 2-digit integer 12

%m Month as 2-digit integer 01

%B Full month name January

%b Abbreviated month name Jan

%d Day as 2-digit integer 04

%j Day of year as 3-digit int 278

%A Full weekday name Friday

%a Abbreviated weekday name Fri

%w Weekday (Sunday=0) 5

%U Week number (Sunday=0) 42

%W Week number (Monday=0) 41

Mehr Infos: http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

Format

Meaning Example

%H Hour as 2-digit int (24 h) 23

%I Hour as 2-digit int (12 h) 11

%M Minute as 2-digit integer 01

%S Second as 2-digit integer 57

%p AM / PM PM

%f Microseconds as 6-digit int 000000

%c = %m/%d/%y %H:%M:%S s.u.

%x = %m/%d/%y 10/31/08

%X = %H:%M:%S 14:09:12

%z UTC offset

%Z Time zone name

%% A % character %

datetime.strftime und datetime.strptime

Kontrolle des Datumsformats beim Einlesen

24

from http://matplotlib.org/api/mlab_api.html#matplotlib.mlab.csv2rec:

Converter dictionary: (Format)umwandlung für einzelne Spalten oder Variablen

Beispiel:

Aufgaben3. Schreibe ein Programm, welches die täglichen Wetterdaten der Station

Bonn-Endenich einliest und dabei das Datum in datetime Objekte umwandelt, die Temperaturen in K und die Windgeschwindigkeit in m/s. Die Datei heißt meteo_record_bonn-endenich_2012.csv (sie befindet sich auf ftp://sv02.meteo.uni-bonn.de/pub/maschu/python/data/meteo_record_bonn-endenich_2012.csv .

4. Lade die stündlich aufgelösten Ozon-Messdaten der GAW Station Barrow eines beliebigen Jahres aus dem World Data Center for Greenhouse Gases (http://ds.data.jma.go.jp) und lese sie ein.

a) Ignoriere die Header-Informationen (32 Kommentarzeilen)b) Lese den Stationsnamen und die Angaben zu Latitude, Longitude und Altitude aus dem

Header mit aus

Löschen/Umbenennen von Dateien

26

Die Module os und shutil enthalten praktisch alles, was man zum Umgang mit Dateien benötigt.

Beispiele:

Nicht ganz so trivial: Löschen von Dateien mit bestimmten Namensmustern (wildcards). Beispiel (Unix) rm ooops* funktioniert mit os.remove() nicht! Auch shutil.rmtree greift da nicht (zumindest, wenn andere Dateien erhalten bleiben sollen).

Arbeiten mit Verzeichnissen

27

Die glob() Funktion aus dem Modul glob wandelt wildcards in eine Liste von Dateien um.

Beispiel:

Beispiel:

Damit können wir nun auch alle ooops* Dateien in einem Rutsch löschen:

Rekursives Löschen kann ganz schön viel Arbeit verursachen!

Verzeichnisse anlegen und (leere) Verzeichnisse löschen geht mit os.mkdir() bzw. os.rmdir(). Ganze Verzeichnisbäume können mit shutil.rmtree() entfernt werden.

Netcdf• „Network Common Data Format“:

Strukturierte Binärdaten mit Metadata-Attributen („selbsterklärend“)• Entwickelt von Unidata (Boulder, CO):

http://www.unidata.ucar.edu/software/netcdf/ • Referenz-API in C, APIs für diverse Programmiersprachen verfügbar• Maschinen-unabhängiges Datenformat

Netcdf Dateien enthalten:Variablen: Datenfelder mit Namen und AttributenDimensionen: Integer-Werte, die die Variablengröße angebenAttribute: Metadaten-Informationen zu den Variablen

Es gibt verschiedene netcdf Varianten. Gebräuchlich sind momentan:• netcdf3 („classic“)• netcdf4 („classic“)• netcdf4/HDF5

Beispiel einer netcdf Dateincl Format (ncdump filename; ncgen filename):

Ein weiteres Beispiel (mehrdimensional)ncl Format (ncdump filename; ncgen filename):

Python netcdf Bibliotheken• netCDF4: http://code.google.com/p/netcdf4-python/

(netcdf3, 4, HDF5: read/write; Linux and Windows)

• PyNio: http://www.pyngl.ucar.edu/Download/ (netcdf 3, 4, HDF4: read/write; GRIB1, 2, HDF-EOS2, 5, shape: read; Linux only)

• SciPy.io.netcdf (in SciPy enthalten; netcdf 3)

Empfohlen wird netCDF4, da es gut funktioniert, viele „Dialekte“ von netcdf unterstützt und aktiv weiterentwickelt wird.

Schreiben von netcdf DateienGeht auch ;-) Benutze dazu die create… Funktionen eines netcdf.Datasets.

Mehr Infos unter http://netcdf4-python.googlecode.com/svn/trunk/docs/netCDF4-module.html.

Datum in netcdf DateienGemäß der netcdf-CF Konvention (siehe http://cf-pcmdi.llnl.gov) werden Datums- und Zeitangaben in netcdf Dateien meist relativ zu einem Referenzdatum angegeben. Dazu sind das units und das calendar Attribut erforderlich:

Mehr Infos unter http://netcdf4-python.googlecode.com/svn/trunk/docs/netCDF4-module.html.

Das netCDF4 Modul stellt die Routinen num2date() und date2num() zur Verfügung, um Zeitangaben einfach in datetime Objekte umzurechnen bzw. datetime Objekte in netcdf CF kompatible Zeitangaben zu übersetzen:

Solutions to excercises

35

3. Let‘s take a look at the file format first:

We have comma-separated values, variable names in the first row, and a date format that can be described as %Y-%m-%d.

will already do most of what we need. However, as a print data.dtype will tell, the dates are stored as date objects (not datetime as we would like) and (of course) no conversions of temperatures or wind speeds took place.

36

3. continued

Let‘s define the necessary conversion functions. Note that each function must take a string as argument and return the value in the appropriate data type.

Next, we must map the variables onto the converter functions.

csv2rec changes all variable names to lower case! The conversions will fail silently if we copy the variable names verbatim including the capitals!

37

3. continued

Now, we can read the data easily (note that the default delimiter is ″,″):

Inspection with print data.dtype and print data[0] should verify that everything works as it should.

There is one minor thing left: the variable names are no longer correct, because we changes units. Let‘s rename them.

We obtain the variable names as n=data.dtype.names. However, this is a tuple, and we cannot change inidividual tuple elements (tuples are „immutable“). Solution: convert to a list, change entries, and convert back:

To convert all names, we make use of another dictionary…

38

3. continued

Note the use of the dictionary‘s get method in the list comprehension. Since we don‘t rename every variable, the term varNameDict[entry] would cause an error for all items not defined. With get(element, default=None), we can specify a default value that shall be used in such cases. This default value is simply the unaltered entry!

You can find the complete program as files_excercise3_csv2rec.py on ftp://sv02.meteo.uni-bonn.de/pub/maschu/python/programs.