Daten aus einer tab-separated Datei lesen

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
burgenix
User
Beiträge: 3
Registriert: Donnerstag 14. Dezember 2017, 10:41

Hallo erstmal,

Hab ein file, welches so aussieht:

a b c
a1 b1 c1
a2 b2 c2
........
a100 b100 c100

Die Elemente sind von ein Tab getrennt. Nun möchte ich eine Summe für c bis c20 und eine andere summe für c80 bis c100 bekommen, ich kriegs nur nicht hin, die lines in einer liste einzulesen und sie mit zwei Tabs zu trennen.

Das hab ich bis jetzt:

Code: Alles auswählen

with open('./output_' + name + '_' + str(count) + '_coverage.txt', 'r') as covfile:
            gencov = covfile.readlines() # a list called gencov where we read the file by line 
            beg_cov = sum(int(gencov.split('\t')[0:20])) / 20
            end_cov = sum(int(gencov.split('\t')[-20:])) / 20
            statistics.write(name + ' ' + beg_cov + ' ' + end_cov + '\n')
            covfile.close()
            statistics.close()
(nur ein teil des scripts)

Any ideas? :D :K

LG!
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

zum Lesen solltest du das csv-Modul nehmen, das ist für sowas gemacht und in Python enthalten. Dann bekommt du pro Zeile eine Liste mit den Werten.

Wenn du mit den Werten Rechnen willst (zeile- oder spatenweise), dann macht es vielleicht Sinn, die Daten direkt in Numpy oder ggf. Pandas zulesen.

Noch einen Anmerkung zu deinem Code: Pfade setzt man mit `os.path.join()` zusmammen. Und String besser mit der `format()`Methode von Strings.

Gruß, noisefloor
burgenix
User
Beiträge: 3
Registriert: Donnerstag 14. Dezember 2017, 10:41

Danke für deine Antwort, hat mich sehr geholfen !

Dies hab ich bis jetzt geschrieben (kann es leider nicht sehr gut zu Hause testen, da die Testdatenmengen sehr groß sind, also erst morgen kann ichs machen).

Code: Alles auswählen

with open('./output_' + name + '_' + str(count) + '_coverage.txt', 'r') as covfile:
                stripped = (line.strip() for line in covfile)
                lines = (line.split("\t") for line in stripped if line)
                    with open('./output_' + name + '_' + str(count) + '_coverage.csv', 'w') as out_file:
                        writer = csv.writer(out_file)
                        writer.writerow(('bait_name', 'position', 'value'))
                        writer.writerows(lines)
                data = np.genfromtxt(str('./output_' + name + '_' + str(count) + '_coverage.csv'), delimiter='\t', skiprows=1, usecols=range(2,))
                beg_cov = float(sum(int(data[0:100])/100)
                end_cov = float(sum(int(data[-100:]))/100)
                statistics_per_bp.write(str(count) + '  ' + float(beg_cov) + '   ' + float(end_cov))
Klingt das einigermaßen richtig? (hab numpy erst wenig benützt, und bin mir wegen usecols nicht sicher) Ich hoffe, es werden nur die werte aus der dritten kolonne gewählt.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du solltest fuer deine Namen string-formatting benutzen:

Code: Alles auswählen

  './output_{}_{}_coverage.txt'.format(name, count)
Und warum du einen CSV-*Writer* aber nicht reader benutzt ist mir auch unklar.

Warum generierst du eine Datei, um sie dann direkt in ein np-Array zu lesen? Du hast die Daten in dem Moment doch schon eingelesen, und genfromtxt sollte doch eigentlich auch gleich auf deiner Ursprungsdatei arbeiten - wozu also dieser Roesselsprung?

Die Berechnung von beg_cov/end_cov sieht Fehlerhaft aus. Wie soll aus 100 Werten ein int werden? Wenn du die zu ints konvertieren willst, musst du dazu die numpy-Funktion "astype" verwenden. Und numpy.sum statt dem normalen sum, damit du ueberhaupt von der erhoeten Geschwindigkeit profitierst.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@burgenix: wenn Du nur die dritte Spalte nehmen willst, mußt Du eine Liste mit einem Element [2] benutzen; genfromtxt kennt »dtype=int«, falls Du wirklich alle Zahlen in Ganzzahlen umwandeln willst. Das Umkopieren in eine neue Datei mit gleichem Inhalt ist unnötig. numpy kennt `mean`. Strings und Floats kann man nicht mit + zusammensetzen; nimm .format.

Code: Alles auswählen

data = np.genfromtxt('output_{}_{}_coverage.txt'.format(name,count), delimiter='\t', skiprows=1, usecols=[2], dtype=int)
beg_cov = data[:100].mean()
end_cov = data[-100:].mean()
statistics_per_bp.write("{} {} {}\n".format(count, beg_cov, end_cov))
burgenix
User
Beiträge: 3
Registriert: Donnerstag 14. Dezember 2017, 10:41

Wow, danke schön ! Schaut super aus :)
Antworten