biologischer Datensatz sinnvoll einlesen

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
blutigerAnfänger
User
Beiträge: 1
Registriert: Montag 29. November 2021, 22:22

Hallo,
ich versuche mich schon seit einigen Wochen daran einen biologischen Datensatz einzulesen, um ihn danach weiter auswerten zu können. Aber ich komme gerade nicht weiter. Es handelt sich um eine csv-Datei mit folgenden Daten:

Genname Experiment1:Wert Experiment1:signifikant Experiment2:Wert Experiment2:signifikant
zzzz 0,11123 0 0,22233 1
ssss 0,66666 1 0,11127 1

Es ist nur ein Beispiel des Datensatzes. Rechts würden sich die Einträge bis zu Experiment 16 fortsetzen und insgesamt 8000 Gene(Zeile) wurden betrachtet. Meine Idee war nun, einzelne Dateien zu erstellen, wo für jedes Experiment nur noch die signifikanten Gene drin stehen(also hier Spalte 3 oder 5 mit dem Wert"1").
Meine erste Idee war, alles als Dictionary einzulesen. Der Genname ist der Key und die Experimente wollte ich als Liste im Value abspeichern. Ist dieser Ansatz überhaupt sinnvoll, um damit weiter zu arbeiten? Wenn ich nach dem Wert "1" filtern möchte, bekomme ich nur einen Boolean zurück. Aber eigentlich will ich ja nur die Zeilen ausgegeben haben, wo die 1 drin steht. Sollte ich da eher eine Funktion schreiben? Und in der Ausgabedatei steht nur eine einzelne "1".

ziel = open("Ziel.txt","w")
with open ('ProteinGroups_Contrasts_1sheet2.csv')as csvdatei:
object = csv.reader(csvdatei, delimiter=',')
header=next(object)
print(header)
for zeile in object:
zeilen = (
(zeile[0], zeile[int(1)]),
(zeile[0], "1" in zeile[(2)])
)
data = {}

for zeile in zeilen:
data.setdefault(zeile[0],[]).append(zeile[1])
for zeile in zeilen:
if "1" in zeile:
ziel.write(data)
print (data)
ziel.close()

Nachdem ich da nicht weitergekommen bin, habe ich es anders versucht. Könnte mir hier jemand verraten, warum mir nur die letzte Zeile meiner Ausgangsdatei ausgegeben wird?
import csv

with open ('ProteinGroups_Contrasts_1sheet2.csv') as csvdatei:
object = csv.reader(csvdatei, delimiter=',')

header=next(object)

for zeile in object:
input={
header[0]: zeile[0],
header[1]: zeile[1],
header[2]: zeile[2],
header[3]: zeile[3],
header[4]: zeile[4],
header[5]: zeile[5],
header[6]: zeile[6],
header[7]: zeile[7],
header[8]: zeile[8],
header[9]: zeile[9],
header[10]: zeile[10],
header[11]: zeile[11],
header[12]: zeile[12], }
print(input)

Ich habe noch nicht so viele Erfahrungen mit Python. Möchte aber gerne mehr damit machen. Habt ihr vielleicht ein paar Tipps, wie ich an mein Problem heran gehen kann.
Ich Danke schon mal im Vorraus.
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@blutigerAnfänger: Als allererstes solltest Du Dir `csv.DictReader` anschauen wenn ich mir das letzte Codebeispiel anschaue. Selbst wenn es diese Klasse nicht gäbe, ist es eigentlich immer falsch so etwas “regelmässiges“ wie das Wörterbuch mit so vielen fast gleichen Zeilen manuell hinzuschreiben, weil das in jeder brauchbaren Programmiersprache besser gehen sollte.

Code: Alles auswählen

            record = {
                header[0]: zeile[0],
                header[1]: zeile[1],
                header[2]: zeile[2],
                header[3]: zeile[3],
                header[4]: zeile[4],
                header[5]: zeile[5],
                header[6]: zeile[6],
                header[7]: zeile[7],
                header[8]: zeile[8],
                header[9]: zeile[9],
                header[10]: zeile[10],
                header[11]: zeile[11],
                header[12]: zeile[12],
            }
            
            # =>
            
            record = dict(zip(header, zeile))
Aber wie gesagt, es gibt `csv.DictReader()`

Erst einmal Anmerkungen zum Quelltext allgemein: Du kennst die ``with``-Anweisung, verwendest die aber bei der Zieldatei nicht!?

Textdateien sollte man immer mit der passenden Kodierung öffnen. Sonst ist das abhängig von den Systemeinstellungen ob das einlesen funktioniert oder nicht, und was beim schreiben als Kodierung verwendet wird.

Das CSV-Modul erwartet, dass die Datei mit dem Argument ``newline=""`` geöffnet wurde, weil sich das selbst um Zeilenendezeichen kümmert. Das steht auch in der Dokumentation vom `csv`-Modul.

`object` ist als Name in aller Regel *viel* zu generisch und ausserdem der Name des eingebaute Datentyps `object`. Solche Namen sollte man in der Regel nicht verdecken, weil das a) verwirrend für den Leser ist, und b) man Probleme bekommt wenn man den Wert dann selbst mal benötigt.

Aus so einem `csv`-Reader-Objekt kommen eher keine Zeilen heraus. Das waren mal Zeilen in der Datei, wobei auch das bei CSV-Dateien nicht generell stimmen muss, das Format kann auch Zeilenumbrüche *in* Zellen, dann erstreckt sich der Datensatz über mehr als eine Zeile wenn man die Datei als Textdatei betrachtet. Womit wir auch schon einen passenderen Namen genannt hätten: Datensatz. Im Englischen hätte man es ”Zeile” nennen können, denn da gibt es einen Unterschied zwischen Tabellenzeile („row“) und Textzeile („line“) wo im Deutschen für beides ”Zeile” die erste Wahl wäre.

Danach wird mir das erste Beispiel ein bisschen zu wirr. Dazu nur noch so viel, dass `dict.setdefault()` so nicht mehr verwendet wird seit es `collections.defaultdict` gibt.

`input` ist der Name einer eingebauten Funktion, den sollte man genau so wenig verdecken wie `object`.

Wenn man mal die umständliche Zuweisung an den Namen mit der Verwendung von `csv.DictReader` überflüssig macht, steht da folgendes:

Code: Alles auswählen

import csv

with open(
    "ProteinGroups_Contrasts_1sheet2.csv", encoding="utf-8-sig", newline=""
) as csv_datei:
    reader = csv.DictReader(csv_datei, delimiter=",")
    for record in reader:
        pass
    print(record)
Warum genau hättest Du jetzt hier erwartet, dass da mehr als nur der letzte Datensatz ausgegeben wird? Das ist nämlich das was der Code sagt. Der sagt *nicht* gib *jeden* Datensatz aus.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten