Daten aus mehreren .dat Dateien in einzelne Sheets in einer einzigen Excel Datei importieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
saibot9393
User
Beiträge: 12
Registriert: Dienstag 11. Juni 2019, 07:02

Ich habe mehrere Dateien vom Typ .dat und möchte diese Dateien in eine einzige Excel-Datei einfügen. Dabei sollte pro Datei ein Excel Sheet erstellt werden und der Inhalt der Datei eingefügt werden. Bisher werden zwar die einzelnen Sheets erstellt, jedoch fehlt noch der Inhalt der Dateien. Jedes Feedback oder Kritik wäre super!

import glob
from os.path import basename

import numpy as np
import pandas as pd
import xlwt

files = glob.glob('Temperatur/*.dat')
writer = pd.ExcelWriter('TemperaturT.xlsx', engine='xlsxwriter')
for file in files:
sheet_name = basename(file)
sheet_name = sheet_name.split('_')[0]
sheet_name = sheet_name[1:]
sheet_name = int(sheet_name)
sheet_name = str(sheet_name)

with open(file, 'r') as f:
l = f.readlines()

bin_files = []
for line in l:
row = line.strip().split(',')
num = row[0]
if num == '211':
#print(row[1])
bin_files.append(row[1])
vars = {}
for name in bin_files:
stem, ext = name.rsplit('.', 1)
assert ext in ['R32', 'R64'], 'Unknown data format'
if ext == 'R32':
a = np.fromfile('temperatur' + '/' + name, dtype=np.float32)
else:
a = np.fromfile('temperatur' + '/' + name, dtype=np.float64)
var_name = stem.split('_', 10)[-1]
if len(a) == 4036:
vars[var_name] = a


df = pd.DataFrame.from_dict(vars)
df.to_excel(writer, sheet_name=sheet_name)

writer.save()
writer.close()
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@saibot9393: Feedback: `xlwt` wird importiert, aber nicht verwendet.

Es gibt einige Operationen auf Pfaden als wenn das normale Zeichenketten wären, wo es aber Funktionen in `os.path` für gibt, die a) Sonderfälle beachten und b) das ganze plattformunabhängig machen.

`files` sollte eher `filenames` heissen. Bei `file` denkt der Leser an Objekte die Methoden wie `read()`/`write()`/`close()`/… haben.

`sheet_name` wird ziemlich weit vor der Verwendung des Wertes definiert. Und eventuell wäre ein regulärer Ausdruck hier einfacher zu verstehen als die vielen Schritte die bei der Verarbeitung des Dateinamens gemacht werden.

Textdateien sollte man immer mit einer konkreten Kodierung öffnen.

Einbuchstabige Namen sind selten eine gute Idee. Es gibt Ausnahmen wie `i` und `j` als ganzzahlige Laufvariablen/Indices oder `x`, `y`, und `z` für Koordinaten – halt so Sachen die jeder aus der Mathematik kennt. Und wenn der Sichtbarkeit sehr begrenzt ist, beispielsweise bei ``lambda``- oder Generatorausdrücken, oder in „comprehensions“. Aber `lines` mit `l` abkürzen ist nicht offensichtlich und auch statt `f` kann man `file` schreiben, ohne das einem die Buchstaben oder der Speicher ausgehen. ;-) Bei `a` weiss ich nicht was das im Programm bedeuten soll.

Es werden unnötig Listen mit Zeilen und Dateinamen aufgebaut. `l` und `bin_files` braucht man so als Liste eigentlich gar nicht.

`vars()` ist der Name einer eingebauten Funktion, die sollte man nicht an etwas anderes binden.

Die beiden Zweige mit den `np.fromfile()`-Aufrufen unterscheiden sich nur durch das `dtype`-Argument. Das liesse sich ohne ``if``/``else`` mit einem Wörterbuch lösen das Dateiendungen auf `dtype`\s abbildet.

Die Definition von `var_name` kann man in das folgende ``if`` ziehen, denn der Name wird ja nicht gebraucht wenn die Bedingung dort nicht erfüllt ist.

Der `pandas.ExcelWriter` ist ein Kontextmanager, den sollte man also mit ``with`` verwenden wenn das geht.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import glob
import os

import numpy as np
import pandas as pd

EXT_TO_DTYPE = {'R32': np.float32, 'R64': np.float64}


def main():
    with pd.ExcelWriter('TemperaturT.xlsx', engine='xlsxwriter') as writer:
        for dat_filename in glob.glob(os.path.join('Temperatur', '*.dat')):
            with open(dat_filename, 'r', encoding='ascii') as lines:
                variables = {}
                for line in lines:
                    number, bin_filename, *_ = line.strip().split(',')
                    if number == '211':
                        stem, ext = os.path.splitext(bin_filename)
                        values = np.fromfile(
                            os.path.join('temperatur', bin_filename),
                            dtype=EXT_TO_DTYPE[ext],
                        )
                        if len(values) == 4036:
                            var_name = stem.split('_', 10)[-1]
                            variables[var_name] = values

            sheet_name = str(
                int(os.path.basename(dat_filename).split('_', 1)[0][1:])
            )
            df = pd.DataFrame.from_dict(variables)
            df.to_excel(writer, sheet_name)

        writer.save()


if __name__ == '__main__':
    main()
Wenn der Inhalt der Dateien fehlt, dann muss ja `df` leer sein. Was es wäre wenn `variables` leer ist. Und da müsstest Du dann halt schauen woran es liegt, das die letzte innerste Zeile nicht ausgeführt wird. Da liegen ja einige Vorbedingungen auf dem Weg dort hin.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten