2016-11-17 7 views
2

Ich brauche einige Informationen aus einem txt-Datei-Header zu lesen, die wie folgt aussehen:Python las TXT-Dateien Header

Date 20160122 
SP Number 8 
Gauge 250N internal 
Total Height 61 
SP Modell SP2 
Corner Distance 150 

Height Value Comment 
60 NaN 
... 

ich ein Python-Programm Programm zur Zeit dies zu tun:

depth, N = npy.loadtxt(filename, skiprows=8, unpack=True, usecols = usecols) 

Allerdings möchte ich einige der Werte aus dem Header vorlesen. Gibt es eine Möglichkeit, dies zu tun? Ich bin hauptsächlich daran interessiert, den Wert von "Gesamthöhe" zu erhalten. Auf meiner Suche finde ich nur Antworten auf .csv-Dateien.

+0

Die Einträge zu lesen in Der Header ist durch ein '\ t'-Trennzeichen getrennt. Also kann ich das als eine sichere Möglichkeit benutzen, die Strings zu teilen. –

Antwort

1

würde ich open statt npy.loadtxt

with open(filename, 'r') as the_file: 
    all_data = [line.strip() for line in the_file.readlines()] 
    height_line = all_data[3] 
    data = all_data[8:] 

Dann können Sie den Wert von height_line, analysieren, um die Gesamthöhe zu erhalten. Und alle Ihre Daten aus der Datei werden in der Variablen data sein.

+0

Wie analysiere ich es und wie bekomme ich die Werte 'N' und' Tiefe' von 'Daten'? –

+0

Ich habe 'height = height_line.split ('\ t') [1]' hinzugefügt und das löst mein Problem gut. Ich habe auch einige Filter mit 'height_line.find ('\ t')', 'math.isnan' und' panda.isnull() 'hinzugefügt und fängt auch Nans und leere Einträge ab. –

1

Dies sollte funktionieren!

field = "Total Height" 

# Get first 6 lines 
with open(filename) as file: 
    lines = [next(file) for x in range(6)] 

value = None 
for line in lines: 
    if line.startswith(field): 
     # Get the part of the string after the field name 
     end_of_string = line[len(field):] 

     # Convert it to an int: 
     value = int(end_of_string.strip()) 

print(value) #Should print 61 

Wenn Sie wissen, dass die Feldnamen und Werte durch ein Tabulatorzeichen getrennt sind, anstelle von Leerzeichen, Sie stattdessen line.split('\t') verwenden könnte jede Zeile in den Feldnamen und Feldwert zu brechen, und dann nur prüfen, ob field_name ist das Feld, das Ihnen wichtig ist, und wenn ja, verwenden Sie den Wert, anstatt startswith zu verwenden und dann die resultierende Zeichenfolge zu schneiden, um das Ende davon zu erhalten.

+0

Es funktioniert. Ich habe nur das Problem, dass einige der Dateien einen 'NaN'-Eintrag oder sogar einen leeren Eintrag haben. Gibt es eine Möglichkeit, das zu filtern? –

+0

Sie könnten die Zeile value = ... in einen try/except-Block setzen, so dass der except-Block die Ausnahme fängt und den Wert gleich None setzt, wenn er versucht, etwas zu analysieren, das keine Zahl ist.Nach Abschluss der for-Schleife können Sie überprüfen, ob der Wert gleich None ist. Wenn nicht, tun Sie Ihre normale Sache, und wenn dem so ist, tun Sie nichts oder fügen Sie etwas Logik für das hinzu, was geschehen sollte, wenn eine Datei eine gute Gesamthöhe nicht spezifiziert hat. Auch, wenn diese Antwort Ihre Frage beantwortet, stört es Sie, sie zu verbessern und als richtig zu markieren? :) –

0

tut es Dies wird aber mit einer Einschränkung:

import numpy as npy 

usecols = (0, 1) 

header = {} 
with open(filename, 'rt') as f: 
    for header_lines, line in enumerate(f): 
     line = line.strip() 
     if not line: break # assume that a blank line means "header stops here" 
     key, value = line.split(' ', 1) 
     header[key] = value 


depth, N = npy.loadtxt(filename, skiprows=header_lines + 2, unpack=True, usecols=usecols) 

Das Problem ist, dass das Header-Format Zweideutigkeit hat, was Schlüssel ist, und was Wert ist. Einige Schlüssel scheinen mehrere durch Leerzeichen getrennte Wörter zu sein, und einige Werte sind es auch, und dennoch (eine nicht-deterministische Menge von) Leerzeichen ist auch anscheinend die einzige Regel für die Trennung von Schlüssel von Wert. In den meisten Fällen sind es 3 Leerzeichen zwischen Schlüssel und Wert, aber Corner Distance wird nur von 1 Leerzeichen gefolgt - es ist daher mehrdeutig (außer für den eigenen komplexen Kontextparser des menschlichen Gehirns), wo der Schlüssel endet und der Wert beginnt.

Vielleicht ist das Problem nur schlechtes Rendering (auf dieser Seite oder beim Kopieren-Einfügen in SO) von dem, was eigentlich Registerkarten sein sollen. Wenn ja,

 key, value = line.split('\t', 1) 

wird das Problem lösen. Wenn nicht, muss die Mehrdeutigkeit im Dateiformat gelöst werden, bevor eine endgültige Lösung geschrieben werden kann.

+0

Damit bekomme ich: 'ValueError: mehr als 1 Wert zum Entpacken benötigt ' –

+0

Klingt, wie es versucht, eine Zeile auf einem Zeichen (z. B.' \ t'') zu trennen, die nicht in der Zeile erscheint. Es war nur eine Vermutung von meiner Seite, dass '\ t' verwendet wurde. Wie ich bereits sagte, gibt es Probleme mit dem Dateiformat, das Sie lösen müssen, bevor Sie fortfahren: Was * ist * die Regel, die Schlüssel von Werten trennt? Der Code in meiner Antwort muss entsprechend der Antwort auf diese Frage angepasst werden, die aus Ihrem Beispiel nicht bestimmt werden kann. – jez

0

Sie können es mit re Modul, wenn Schlüssel in Header-Datei sind immer die gleichen:

file = open(filename, 'r') 
data = file.read() 
Total = re.findall('Total Height\s*([0-9]+)\s*\n', data)[0] 

Ich hatte die gleiche Aufgabe, die Header-Datei und did it mit re Modul

+0

Aber beschränkt sich das nicht auf Zahlen als Einträge? Ich habe dort auch Briefeinträge. –

+0

@ brium-brium können Sie ersetzen '([0-9] +)' mit '(. +?)' Und es findet alle Zeichen nach Leerzeichen und vor Newline – Greg