Seite 1 von 1
Daten-Suche
Verfasst: Sonntag 5. April 2009, 14:11
von ete
Hallo!
Ich habe ein Problem, beidem ich nicht weiterkomme:
Ich habe 2 Datensätze:
1)
CONTIG SEQUENZ
contig1 U35_12
contig1 U35_156
contig1 U35_89
contig2 U35_23
contig2 U35_9789
2)
SEQUENZ PVALUE
U35_12 568
U35_156 12
U35_89 79
U35_23 13
U35_9789 66
Ich möchte pro CONTIG die SEQUENZ mit dem niedrigsten PVALUE haben, also:
CONTIG SEQUENZ PVALUE
contig1 U35_156 12
contig2 U35_23 13
Ein weiteres Problem ist, dass der Datensatz ziemlich gross ist (2 x 51000 Zeilen). Ich wollte über eine SQlite3 Datenbank gehen aber alleine diese zu generieren dauert Stunden. Wie kann man sowas am Besten (und schnellesten) lösen? Über dict bräuchte man ja quasi ein dict im dict:
Geht sowas?
Bin für jeden Hinweis dankbar!
Liebe Grüsse
Stefanie
Verfasst: Sonntag 5. April 2009, 14:36
von jerch
Mit einem solchem Dict könntest Du bei Deinem Datenvolumen schnell an die Grenzen Deiner Hardware stoßen, sprich der RAM geht Dir aus oder der Interpreter meckert über zu große Dicts (ist wiederum RAM beschränkt). Sind die "contig*"-Einträge relativ überschaubar, kannst Du das mit einem Dict lösen, ich würde aber als value nur den jeweils kleinsten gefunden Wert eintragen, also den value updaten, falls der neue kleiner ist als der im Dict befindliche.
Sollte selbst dieses Dict noch zu groß sein (für sehr viele "contig*"-Einträge), müßtest Du die Datensätze vorher auftrennen. Du könntest z.B. alle zu einem contig-gehörigen PVALUEs in ein tempfile schreiben und danach den kleinsten herausfischen.
Verfasst: Sonntag 5. April 2009, 14:56
von EyDu
Wenn das ganze offline laufen soll, würde ich einfach ein Dictionary mit den Minima anlegen und dann mit Brute-Force alle Zeilen vergleichen. Das dauert dann zwar ein paar Minuten, aber das ist immer noch schneller als eine effiziente Implementierung zu basteln.
Verfasst: Sonntag 5. April 2009, 17:07
von b.esser-wisser
Ich kann dir echt nicht glauben, dass 3MB Text in eine SQlite-Datenbank einfügen merklich dauert.
Deshalb hab ich
dieses Programm zusammengehackt (und meine SQL-Kenntnisse aufgefrischt - ich mach das ja nicht total uneigennützig
)
Die drei Konstanten am Anfang müssten dann angepasst werden:
- CONTIG_SEQUENZ, SEQUENZ_PVALUE sind Dateiobjekte - z.B. mit open(), erzeugt.
- DBNAME ist der Dateiname für sqlite(), bei ":memory:" bleibt die Datenbank im RAM
hth, Jörg
Verfasst: Sonntag 5. April 2009, 18:20
von derdon
Warum importierst du itertools in der main-Funktion?
Verfasst: Sonntag 5. April 2009, 19:33
von b.esser-wisser
derdon hat geschrieben:Warum importierst du itertools in der main-Funktion?
Hab ich beim Aufräumen vor dem posten übersehen - bei meinen ersten Tests sahen die Test-Daten anders aus:
Code: Alles auswählen
#besser zum Experimentieren, aber unpraktisch:
TESTDATA = {
"CONTIG SEQUENZ":(
("contig1", "U35_12"),
("contig1", "U35_156"),
("contig1", "U35_89"),
("contig2", "U35_23"),
("contig2", "U35_9789"),
),
"SEQUENZ PVALUE":(
("U35_12", 568),
("U35_156", 12),
("U35_89", 79),
("U35_23", 13),
("U35_9789", 66),)}
(RegEx-search&replace sei dank
)
hth, Jörg
Verfasst: Montag 6. April 2009, 08:43
von ete
b.esser-wisser hat geschrieben: bei ":memory:" bleibt die Datenbank im RAM
hth, Jörg
Danke, das wusste ich nicht
Das hat mein Problem gelöst
Vielen Dank!
Stefanie
Verfasst: Montag 6. April 2009, 11:30
von ete
Hab noch ein Problem:
im Ganzen Datensatz wird nur ein Hit gefunden
Picke ich mir aus dem Ganzen ein kleines Bespiel raus, wird dieses problemlos ausgeführt
Woran kann das liegen?
Hier mal die Daten:
http://www.snowflake-sl.info/posting/Python%20Fourm.rar
Wäre nett wenn jemand mal draufschauen könnte...Alles sehr merkwürdig oder ich seh den Wald vor lauter Bäumen nicht...
Danke
Verfasst: Montag 6. April 2009, 14:17
von b.esser-wisser
Ändere mal den letzten SQL-Query wie folgt:
Code: Alles auswählen
cursor = con.execute("""\
SELECT c.name, pvalue
FROM contigs AS c
JOIN sequence_pvalues AS sp
ON sequence
GROUP BY (c.name)
""")
... und wenn du die
StringIO-Objecte durch "echte"
file-Objekte ersetzt, brauchst du nicht mal 10000 Zeilen Müll in "unser" Programm kopieren, sondern kannst deine Textdateien verwenden.
hth, Jörg
Verfasst: Montag 6. April 2009, 15:02
von ete
b.esser-wisser hat geschrieben:brauchst du nicht mal 10000 Zeilen Müll in "unser" Programm kopieren, sondern kannst deine Textdateien verwenden.
hth, Jörg
Hab ich vergessen rausszuschmeissen, sorry.
Danke, es tut sich was (Rechner rechnet noch). Kannst du bitte kurz erklären warum er nur einen Hit gefunden hat?
@Edit:
Dasselbe Ergbnis mit verändertem Code. Wieder nur ein Hit
Lg
Verfasst: Montag 6. April 2009, 17:02
von b.esser-wisser
Bei mir geht's aber (der Satz ist mal ein echter Klassiker
).
Weil es tatsächlich ein bisschen zu lang dauert, habe ich mal einen Index eingebaut:
Dieses Programm braucht bei mir ca. 6s, wenn die Datenbank erstellt wird (2s wenn sie wiederverwendet wird). Einfach die beiden .txt-Dateien aus deinem Archiv in den selben Ordner kopieren und starten.
hth, Jörg
Verfasst: Montag 6. April 2009, 17:09
von ete
Oh, vielen Dank das funktioniert!
Konnte von deinem Code viel Lernen! Danke!
Liebe Grüsse und schönen Feierabend!
Stefanie
Verfasst: Mittwoch 8. April 2009, 11:27
von ete
Hallo!
Hab doch noch ein Problem:
Jetzt sucht er den mittleren Wert heraus. Bsp.
(u'Contig9913', u'U35_33989', 0.223)
(u'Contig9913', u'U35_37449', 0.81600000000000006)
(u'Contig9913', u'U35_16441', 0.78300000000000003)
ergibt:
Contig9913, 0.783000
Danke nochmal.
Stefanie
Edit:
Sorry hat sich erledigt. War mein Fehler
OT: Shell-Lösung
Verfasst: Mittwoch 8. April 2009, 13:50
von lutz.horn
Ein Vorschlag, der nichts mit Python zu tun hat:
Code: Alles auswählen
#!/bin/sh
cat CONTIG_SEQUENZ | cut -f1 -d" " | sort -u |
while read contig
do
join CONTIG_SEQUENZ SEQUENZ_PVALUE -1 2 | grep $contig | sort -k 3 -n | head -1
done
Für die jeweils 50.000 Zeilen großen Dateien
CONTIG_SEQUENZ und
SEQUENZ_PVALUE benötigt dieses Skript auf meiner Maschine ca. 6 Sekunden.
Der Kern dieser Lösung ist der zweckmäßige Einsatz von
join und
sort