2.4.3. Dateien#

Das Arbeiten von Dateien ist insbesondere für die Datenauswertung wichtig. In diesem Kapitel wird der Umgang mit Textdateien, welche Daten enthalten, vorgestellt. Dazu gehört das Öffnen einer Datei, das zeilenweise Auslesen und das Schließen der Datei.

Im Folgenden wird eine generalistischer Ansatz zum Einlesen von Dateiinhalaten vorgestellt. Spezielle Methoden werden dann im Kapitel Datenanalyse vorgestellt.

Die in diesem Kaptiel verwendeten Dateien sind als Archiv hier abgelegt.

Dateien öffnen und schließen#

Um einen Zugriff auf eine Datei zu bekommen, muss diese fürs Lesen oder Schreiben geöffnet werden. Dazu kann die Funktion open verwendet werden. Diese nimmt zwei Argumente, den Pfad der Datei und den Zugriffsmodus, an und liefert ein Dateiobjekt zurück. Über dieses Objekt erfolgt dann der Zugriff auf die Inhalte der Datei.

datei = open('dateien/wuppertal.txt', 'r')

Als Zugriffsmodus stehen folgende Optionen zur Verfügung:

Modul

Beschreibung

r

lesender Zugriff

w

Schreibzugriff, Datei wird überschrieben

a

Schreibzugriff, Inhalte werden angehängt

Nach dem Durchführen der Operationen, sollte die Datei geschlossen werden und somit für den Zugriff durch andere Programme freigegeben werden.

Beinhalten die Textdateien Zeichen, welche nicht im ASCII-Format gespeichtert sind, kann es je nach Pyhton-Interpreter notwendig sein, dies beim Aufruf der open-Funktion anzugeben. An dieser Stelle kann die UTF-8 Kodierung angegeben werden, denn damit sind die meisten Anwendungsfälle abgedeckt. Beinhaltet die Datei nur Zahlen ist dies nicht notwendig.

datei = open('dateien/wuppertal.txt', 'r', encoding='UTF-8')

Zum Schließen kann die close-Methode verwendet werden.

datei.close()

Inhalt einlesen#

Im Allgemeinen wird eine Datei mit der open-Funktion im Textmodus geöffnet. Das heisst, dass ihr Inhalt als Zeichenketten ausgegeben wird.

Um den gesamten Inhalt einer Textdatei einzulesen kann die read-Methode verwendet werden.

datei = open('dateien/wuppertal.txt', 'r', encoding='UTF-8')

inhalt = datei.read()

datei.close()

print( "Inhalt der Datei:")
print( "=================")
print( inhalt )
print()
print( "Länge der Zeichenkette: ", len(inhalt))
Inhalt der Datei:
=================
Aus Wikipedia: Wuppertal ist mit 354.382 Einwohnern (31. 
Dezember 2018) die größte Stadt und das Industrie-, 
Wirtschafts-, Bildungs- und Kulturzentrum des Bergischen 
Landes im Westen Deutschlands. Die „Großstadt im Grünen“ 
liegt südlich des Ruhrgebiets im Regierungsbezirk 
Düsseldorf und ist als siebzehntgrößte Stadt Deutschlands 
eines der Oberzentren des Landes Nordrhein-Westfalen. Die 
Stadt ist Teil der Metropolregionen Rhein-Ruhr und 
Rheinland, des Landschaftsverbands Rheinland sowie des 
Bergischen Städtedreiecks.

Länge der Zeichenkette:  530

Neben dem instantanen Einlesen des gesamten Inhalts, kann die Datei auch zeilenweise mit der readline-Methode gelesen werden. Dabei bilden die Zeilenendzeichen die Trennung zwischen den einzelnen Zeilen.

Sollen beispielsweise nur die ersten drei Zeilen eingelesen werden, so kann dies mit einer einfachen for-Schleife erfolgen.

datei = open('dateien/wuppertal.txt', 'r', encoding='UTF-8')

for i in range(3):
    zeile = datei.readline()
    print(f"Inhalt Zeile {i}:")
    print(zeile)

datei.close()
Inhalt Zeile 0:
Aus Wikipedia: Wuppertal ist mit 354.382 Einwohnern (31. 

Inhalt Zeile 1:
Dezember 2018) die größte Stadt und das Industrie-, 

Inhalt Zeile 2:
Wirtschafts-, Bildungs- und Kulturzentrum des Bergischen 

Eine weitere Möglichkeit des Auslesens ist die Nutzung des Dateiobjekts als Sequenz, bei welcher jede Zeile der Datei einem Element entspricht.

datei = open('dateien/wuppertal.txt', 'r', encoding='UTF-8')

i = 0
for zeile in datei:
    print(f"Inhalt Zeile {i}, mit {len(zeile)} Zeichen:")
    print(zeile)
    i += 1

datei.close()
Inhalt Zeile 0, mit 58 Zeichen:
Aus Wikipedia: Wuppertal ist mit 354.382 Einwohnern (31. 

Inhalt Zeile 1, mit 53 Zeichen:
Dezember 2018) die größte Stadt und das Industrie-, 

Inhalt Zeile 2, mit 58 Zeichen:
Wirtschafts-, Bildungs- und Kulturzentrum des Bergischen 

Inhalt Zeile 3, mit 58 Zeichen:
Landes im Westen Deutschlands. Die „Großstadt im Grünen“ 

Inhalt Zeile 4, mit 51 Zeichen:
liegt südlich des Ruhrgebiets im Regierungsbezirk 

Inhalt Zeile 5, mit 59 Zeichen:
Düsseldorf und ist als siebzehntgrößte Stadt Deutschlands 

Inhalt Zeile 6, mit 59 Zeichen:
eines der Oberzentren des Landes Nordrhein-Westfalen. Die 

Inhalt Zeile 7, mit 52 Zeichen:
Stadt ist Teil der Metropolregionen Rhein-Ruhr und 

Inhalt Zeile 8, mit 56 Zeichen:
Rheinland, des Landschaftsverbands Rheinland sowie des 

Inhalt Zeile 9, mit 26 Zeichen:
Bergischen Städtedreiecks.

Mehrere Dateien einlesen#

Um mehrere Dateien einzulesen kann entsprechend eine Schleife über alle zu lesenden Dateien erstellt werden. Ist diese Liste jedoch nicht bekannt und soll z.B. über alle Dateien mit bestimmten Merkmalen iteriert werden, kann das glob-Modul verwendet werden.

Mit der glob-Funktion des glob-Moduls kann nach Dateinamen gesucht werden. Dabei können auch Platzhalter, sogenannte Wildcards, verwendet werden:

Wildcard

Funktion

*

beliebige Zeichenfolge

?

ein beliebiges Zeichen

[]

alle in den Klammern eingeschlossenen Zeichen

Folgender Aufruf listet alle Dateien im Verzeichnis dateien auf:

import glob

l1 = glob.glob('dateien/*')

print(f"Anzahl der gefundenen Dateien: {len(l1)}")
print("Dateienliste:")
for i in l1:
    print("  ", i)
Anzahl der gefundenen Dateien: 7
Dateienliste:
   dateien/bochum.txt
   dateien/zahlen.csv
   dateien/juelich.txt
   dateien/unwichtig.dat
   dateien/wuppertal.txt
   dateien/tabelle.csv
   dateien/neue_datei.txt

Soll beispielsweise nur nach Dateien mit der Endung .txt gesucht werden, kann dies entsprechend in dem Suchschema angegeben werden:

l2 = glob.glob('dateien/*.txt')

print(f"Anzahl der gefundenen Dateien: {len(l2)}")
print("Dateienliste:")
for i in l2:
    print("  ", i)
Anzahl der gefundenen Dateien: 4
Dateienliste:
   dateien/bochum.txt
   dateien/juelich.txt
   dateien/wuppertal.txt
   dateien/neue_datei.txt

So kann beispielsweise die erste Zeile aller gefundenen Dateien ausgegeben werden:

l3 = glob.glob('dateien/*.txt')

for dname in l3:
    datei = open(dname, 'r', encoding='UTF-8')
    zeile = datei.readline()
    datei.close()
    
    print(f"Erste Zeile der Datei '{dname}':")
    print(zeile)
Erste Zeile der Datei 'dateien/bochum.txt':
Aus Wikipedia: Die Stadt Bochum [ˈboːxʊm] (westfälisch: 

Erste Zeile der Datei 'dateien/juelich.txt':
Aus Wikipedia: Jülich liegt an der Rur. Das zugehörige 

Erste Zeile der Datei 'dateien/wuppertal.txt':
Aus Wikipedia: Wuppertal ist mit 354.382 Einwohnern (31. 

Erste Zeile der Datei 'dateien/neue_datei.txt':
Hallo Dateiwelt!

Dateien schreiben#

Wird eine Datei im Schreibmodus w geöffnet, kann sie mit Inhalt beschrieben werden. Dazu wird die write-Methode eines Dateiobjekts verwendet, welches als Argument die zu schreibende Zeichenkette enthält.

# Ursprüngliche Liste der Datein 
l4 = glob.glob('dateien/*')
print("Dateienliste nach dem Erstellen der neuen Datei:")
for i in l4:
    print("  ", i)
Dateienliste nach dem Erstellen der neuen Datei:
   dateien/bochum.txt
   dateien/zahlen.csv
   dateien/juelich.txt
   dateien/unwichtig.dat
   dateien/wuppertal.txt
   dateien/tabelle.csv
# Öffne Datei zum Schreiben
datei = open('dateien/neue_datei.txt', 'w')

# Schreibe einfachen Inhalt
datei.write('Hallo Dateiwelt!')

# Schließe die Datei
datei.close()
# Neue Liste der Datein 
l5 = glob.glob('dateien/*')
print("Dateienliste nach dem Erstellen der neuen Datei:")
for i in l5:
    print("  ", i)
Dateienliste nach dem Erstellen der neuen Datei:
   dateien/bochum.txt
   dateien/zahlen.csv
   dateien/juelich.txt
   dateien/unwichtig.dat
   dateien/wuppertal.txt
   dateien/tabelle.csv
   dateien/neue_datei.txt

Wie gewohnt kann der Inhalt der neuen Datei eingelesen und ausgegeben werden:

datei = open('dateien/neue_datei.txt', 'r')
inhalt = datei.read()
datei.close()

print(inhalt)
Hallo Dateiwelt!

Daten interpretieren#

Numerische Daten können als Textdateien gespeichert werden. Um diese zu Verarbeiten, müssen die Zeichenketten, welche diese Werte darstellen, interpretiert werden. Dazu können die Funktionen int und float verwendet werden.

str_a = "88"
str_b = "1.3E2"
print(str_a, str_b)
print(type(str_a))

a = int(str_a)
b = float(str_b)

print(a, b)
print(type(a))
88 1.3E2
<class 'str'>
88 130.0
<class 'int'>

Im folgenden Beispiel wird die Datei dateien/zahlen.csv zeilenweise eingelesen und die Werte jeder Zeile als Gleitkommazahl interpretiert. Am Ende wird die Summe aller Einträge gebildet.

# Inhalt der Datei (nur zur Darstellung)
datei = open('dateien/zahlen.csv')
print(datei.read())
datei.close()
45
-12
2.3
-114
37
67.3 
datei = open('dateien/zahlen.csv')

summe = 0
for zeile in datei:
    zahl = float(zeile)
    summe += zahl
    print(f"aktuelle Zahl: {zahl:6}; Zwischensumme: {summe:6.2f}")

print(f"\nSumme: {summe:6.2f}")

datei.close()
aktuelle Zahl:   45.0; Zwischensumme:  45.00
aktuelle Zahl:  -12.0; Zwischensumme:  33.00
aktuelle Zahl:    2.3; Zwischensumme:  35.30
aktuelle Zahl: -114.0; Zwischensumme: -78.70
aktuelle Zahl:   37.0; Zwischensumme: -41.70
aktuelle Zahl:   67.3; Zwischensumme:  25.60

Summe:  25.60

Befinden sich mehrere Zahlen in einer Zeile, so müssen diese durch ein Trennzeichen, z.B. ein Komma ,, getrennt sein. Ist dieses bekannt, so kann nach dem Einlesen die Zeile entsprechent getrennt werden. Hierzu kann die split-Methode der Zeichenketten verwendte werden. Sie gibt eine Liste alle vom Trennzeichen getrennten Elemente zurück.

s1 = "4, 5, -11, 3, 0, -2"
str_elemente = s1.split(',')
print(f"Zeichenkette: {s1}")
print(f"Getrennte Liste: {str_elemente}")
Zeichenkette: 4, 5, -11, 3, 0, -2
Getrennte Liste: ['4', ' 5', ' -11', ' 3', ' 0', ' -2']

Nun sind die getrennten Elemente aber noch Zeichenketten und müssen in Zahlen umgewandelt werden:

elemente = []
for el in str_elemente:
    zahl = float(el)
    elemente.append(zahl)
    
print(f"Getrennte Liste: {elemente}")
Getrennte Liste: [4.0, 5.0, -11.0, 3.0, 0.0, -2.0]

Im folgenden Beispiel wird eine Datei mit jeweils zwei Einträgen pro Zeile, d.h. zwei Spalten, eingelesen und jeweils eine Liste pro Spalte generiert.

# Inhalt der Datei (nur zur Darstellung)
datei = open('dateien/tabelle.csv')
print(datei.read())
datei.close()
1,1
2,4
3,9
4,16
5,25
6,36
7,49
8,64
datei = open('dateien/tabelle.csv')

# leere Listen, welche mit jedem Zeilendurchlauf gefüllt werden
spalte_x = []
spalte_y = []

# Iteration durch die Tabellendatei 
for zeile in datei:
    # Aufspaltung der Zeile, mit `,` als Trennzeichen
    str_elemente = zeile.split(',')
    # Umwandlung Zeichenkette in Gleitkommazahl
    x = float(str_elemente[0])
    y = float(str_elemente[1])
    # Füllen der Listen
    spalte_x.append(x)
    spalte_y.append(y)

# Datei schließen
datei.close()

# Ausgabe der Ergebnislisten
print("Spalte x:", spalte_x)
print("Spalte y:", spalte_y)
Spalte x: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
Spalte y: [1.0, 4.0, 9.0, 16.0, 25.0, 36.0, 49.0, 64.0]