Daten-Suche

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.
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Daten-Suche

Beitragvon ete » Sonntag 5. April 2009, 14:11

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:

Code: Alles auswählen

 (d = {'contig1':('U35_12':568), ('U35_156':12)...})
Geht sowas?

Bin für jeden Hinweis dankbar!
Liebe Grüsse
Stefanie
jerch
User
Beiträge: 1622
Registriert: Mittwoch 4. März 2009, 14:19

Beitragvon jerch » Sonntag 5. April 2009, 14:36

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.
EyDu
User
Beiträge: 4868
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Sonntag 5. April 2009, 14:56

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.
Das Leben ist wie ein Tennisball.
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Beitragvon b.esser-wisser » Sonntag 5. April 2009, 17:07

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
Wir haben schon 10% vom 21. Jahrhundert hinter uns!
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Beitragvon derdon » Sonntag 5. April 2009, 18:20

Warum importierst du itertools in der main-Funktion?
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Beitragvon b.esser-wisser » Sonntag 5. April 2009, 19:33

derdon hat geschrieben:Warum importierst du itertools in der main-Funktion?

:oops: 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
Wir haben schon 10% vom 21. Jahrhundert hinter uns!
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Beitragvon ete » Montag 6. April 2009, 08:43

b.esser-wisser hat geschrieben: bei ":memory:" bleibt die Datenbank im RAM

hth, Jörg


Danke, das wusste ich nicht :D
Das hat mein Problem gelöst :wink:

Vielen Dank!
Stefanie
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Beitragvon ete » Montag 6. April 2009, 11:30

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
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Beitragvon b.esser-wisser » Montag 6. April 2009, 14:17

Ä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
Wir haben schon 10% vom 21. Jahrhundert hinter uns!
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Beitragvon ete » Montag 6. April 2009, 15:02

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
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Beitragvon b.esser-wisser » Montag 6. April 2009, 17:02

Bei mir geht's aber (der Satz ist mal ein echter Klassiker :lol: ).
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
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Beitragvon ete » Montag 6. April 2009, 17:09

Oh, vielen Dank das funktioniert!
Konnte von deinem Code viel Lernen! Danke!

Liebe Grüsse und schönen Feierabend!
Stefanie
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Beitragvon ete » Mittwoch 8. April 2009, 11:27

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 :wink:
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

OT: Shell-Lösung

Beitragvon lutz.horn » Mittwoch 8. April 2009, 13:50

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

Wer ist online?

Mitglieder in diesem Forum: Baidu [Spider], jan.b