Frage von PrettyAna, 123

Einzelne Zahlen aus txt-Dateien in Python einlesen?

Guten Tag.

Ich lerne zur Zeit Python an der Hochschule und arbeite mit Python 3.5. Bisher kam ich immer gut zurecht, doch nun haben wir eine Hausübung bekommen, die mir etwas Kopfzerbrechen bereitet.

Die Aufgabe ist folgende:

Lesen Sie aus der Datei unip-mini.dat.txt Zeile SQ die Länge aller Proteine in eine Liste. Plotten Sie die Liste als Histogramm mit 50 Balken.

Beispiel, wie so eine Zeile aussieht: SQ SEQUENCE 458 AA; 53921 MW; E46E5C85D7ACA139 CRC64;

Länge: 458

Wie man grundsätzlich Dateien in Python einliest, ist mir bekannt. Ich bin auch schon so weit, dass es nur diejenigen Zeilen einliest, die eben mit SQ beginnen. Allerdings möchte ich ja nur die Länge der Proteine in der Liste haben. Nun ist mein Problem, dass ich eben nicht weiß, wie ich es fertig stelle, dass lediglich die Länge in die Liste eingefügt wird.

Mein Code sieht bisher wie folgt aus:

    #!/usr/bin/python3

    import numpy as np
    import matplotlib.mlab as mlab
    import matplotlib.pyplot as plt

    def main():
        if os.path.isfile(sys.argv[1]) == False:
            print("Datei", sys.argv[1], "nicht gefunden")
            exit(0)
        with open(sys.argv[1]) as filetoread:
            lines = filetoread.readlines()
        seq = []

        for i in range(len(lines)):
            if(re.search('SQ   ', lines[i])):
                seq.append(lines[i])

        print(seq)


    if __name__ == "__main__":
        import sys
        import os
        import string
        main()

Könnte mir da vielleicht jemand helfen? Vielleicht gehe ich die Sache ja gerade auch einfach ganz falsch an und merke es nicht.

Mit freundlichen Grüßen

Expertenantwort
von TeeTier, Community-Experte für programmieren, 72

Die anderen Antworten sind teilweise ganz OK, aber ich möchte dich noch auf einige Punkte hinweisen, die du dir UNBEDINGT merken solltest, und die dir in Zukunft viel Ärger ersparen werden:

A) Deine Dateien liegen nicht immer nur im ASCII Format vor, und du solltest beim Lesen und Schreiben derselben auf jeden Fall die Textkodierung beachten.

B) Gerade in deinem Anwendungsfall der Bioinformatik, Biochemie, Molekularbiologie, etc. hast du es häufig mit Dateien zu tun, die richtig lang sind, evtl. sogar einige Terabyte groß. Deshalb vermeide es am besten, deine zeilenweise vorliegenden Daten vorab komplett in eine Liste einzulesen, und iteriere Zeile für Zeile darüber. Bei z. B. einer 10GB großen Datei benötigst du dann nicht mehr mindestens 10GB RAM, sondern nur noch wenige Kilobyte für den Zeilenpuffer.

C) Lerne unbedingt, was Reguläre Ausdrücke sind und wie man damit umgeht. In Python gibt es dafür das "re" Modul, und du kannst dir oftmals sehr viel Tipparbeit sparen, wenn du statt 50 Zeilen Pythoncode einfach eine halbe Zeile RegEx schreibst.

Da du dich ja schon ganz gut auszukennen scheinst, reduziere ich folgendes Beispiel mal auf die wichtigsten drei oben angesprochenen Punkte. Den Rest bekommst du selber hin:

import codecs, re

pat = re.compile('SQ\\s+\\w+\\s+(\\d+)', re.I)

with codecs.open('seq.dat', 'r', 'UTF-8', 'strict') as fh:
for line in fh:
match = pat.match(line)

if match:
length = int(match.group(1))

print('Protein Länge: %d' % length)

Falls das für dich verwirrend aussieht: Das geht allen Anfängern bei RegEx so! Aber es ist wirklich sehr leicht zu verstehen! Und wie du aus dem obigen Snippet dein Histogram basteln kannst, findest du auf jeden Fall auch schon alleine raus. :)

Lies dir unbedingt die Dokumentation zu Modulen durch, die du nicht sofort verstehst und nimm dir unbedingt Zeit um Reguläre Ausdrücke zu lernen! Die darin investierte Zeit sparst du später 1000 fach wieder ein.

Viel Erfolg! :)

Antwort
von Graueumel, 46

Für das Einlesen von strukturierten Textdateien kannst Du auch das Python-Modul Pandas benutzen, genaugesagt die I/O-Funktionen davon: http://pandas.pydata.org/pandas-docs/stable/io.html (Viele Beispiele unten).

Damit lassen sich strukturierte Textdateien, wie z.B. CSV, auch mit Headerzeilen und allem was dazugehört einlesen; meist braucht es nur einen Einzeiler um alle Daten in den Speicher zu bekommen. Auch Excel-Dateien kann man damit lesen und schreiben.

Antwort
von Schachpapa, 53

Python ist eine der schönsten Prg Sprachen.

Ich würde split benutzen.

wenn in lines[i] die mit SQ beginnende Zeile stehlt machst du:

elements = lines[i].split()
anzahl = elements[-1]
seq.append(anzahl)

Das zerlegt dir die Zeile zunächst in durch whitespaces (lerrzeichen, tabs usw) getrennte Stück, von denen das letzte Stück das gesuchte ist. Müsste so gehen.

Kommentar von PrettyAna ,

Auch dir schon mal danke für den Lösungsansatz. 

Antwort
von Allekatrase, 54

Sieh dir einmal Slicing an (https://docs.python.org/2/tutorial/introduction.html):

if(re.search('SQ   ', lines[i])):
seq.append(lines[i][13:15])

Müsste jetzt, wenn ich die Syntax richtig hab, Zeichen 13-15 nehmen. Falls das nicht geht, müsstest du es eventuell vorher noch einmal in einer Variable speichern. Falls es nicht immer 3 Zeichen sind, müsstest du mit Verzweigungen, oder einer Suche arbeiten.


Kommentar von PrettyAna ,

Vielen Dank, ich werde das mal versuchen.

Keine passende Antwort gefunden?

Fragen Sie die Community