Iteration durch String-Wort in einer Zeit, in Python
Ich habe einen string-Puffer, der eine riesige text-Datei. Ich Suche eine VORGEGEBENE Wörter/Sätze in den string-Puffer. Was ist der effizienteste Weg, es zu tun ?
Versuchte ich mit re-Modul entspricht. Aber ich habe einen großen text-corpus, die ich durchsuchen müssen. Diese nimmt jede Menge Zeit.
Gegeben, ein Wörterbuch der Wörter und Sätze.
Ich Durchlaufen, die jede Datei Lesen, die in einer string-Suche alle Wörter und Sätze im Wörterbuch und erhöht die Anzahl im Wörterbuch dann, wenn die Schlüssel gefunden.
Eine kleine Optimierung, die wir dachten, war die Sortierung der Wörterbuch der Phrasen/Wörter mit der max Anzahl der Wörter zu den niedrigsten. Und dann vergleichen Sie in jedem word-start-position von string-Puffer und vergleichen Sie die Liste der Wörter. Falls ein Satz gefunden wird, brauchen wir suchen für die anderen Sätze (da passte es der längste Satz ,das ist, was wir wollen)
Kann jemand vorschlagen, wie man über das Wort in der Zeichenfolge buffer. (Iterate-string-Puffer Wort für Wort) ?
Außerdem gibt es jede andere Optimierung, die getan werden kann auf dieser ?
data = str(file_content)
for j in dictionary_entity.keys():
cnt = data.count(j+" ")
if cnt != -1:
dictionary_entity[j] = dictionary_entity[j] + cnt
f.close()
was ist ein Korpus?
sind Sie der Umsetzung einer Wort - /Satz-counter oder was?
ja, die Implementierung einer Wort - /Satz-Zähler. Corpus ist die string-Puffer, die ich durch suchen. Es gibt Millionen von Dateien, von denen ich habe, um die Anzahl aller vorkommen des Wortes/phrase(Das ist voreingestellt)
Also wenn ich "City of Gold", "Stadt" und "Gold" in meinem hash-Wörter/Sätze-Liste. Und in der Sting-buffer "Dies ist die Stadt von Gold" . Dann mein counter erhöht werden soll, nur für die "City of Gold".
InformationsquelleAutor AlgoMan | 2010-05-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Iteration Wort für Wort durch den Inhalt einer Datei (der Zauberer von Oz aus dem Projekt Gutenberg, in meinem Fall) drei verschiedene Möglichkeiten:
Ergibt:
InformationsquelleAutor Matt Anderson
Das klingt wie die Art von problem, in denen eine trie wirklich helfen würde. Sie sollten wahrscheinlich verwenden irgendeine Art von komprimierten trie wie ein Patricia/radix trie. So lange wie Sie können passen die ganze Wörterbuch der Wörter/Phrasen, die Sie suchen im trie, dies wird erheblich die Zeit reduzieren, die Komplexität. Wie es funktioniert ist nehmen Sie den Anfang eines Wortes und absteigen, die versuchten, bis Sie das längste match und erhöhen Sie den Zähler in diesem Knoten. Dies könnte bedeuten, dass Sie haben, um aufzusteigen, die versuchten, wenn eine teilweise übereinstimmung nicht pan out. Dann würden Sie gehen an den Anfang des nächsten Wortes zu gehen und es wieder tun. Der Vorteil der Marina ist, dass Sie die Suche durch das gesamte Wörterbuch mit jeder Suche durch die trie (jede look-up sollte etwa O(m) wobei m die Durchschnittliche Länge eines Wortes/Satz in deinem Wörterbuch).
Wenn Sie nicht fit das gesamte Wörterbuch in einer Marina, dann könnte man die split-das Wörterbuch, in ein paar versuchen (einer für alle Wörter/Redewendungen beginnend mit a-l, m-z zum Beispiel), und führen Sie einen sweep durch den gesamten Korpus für die einzelnen versuche.
Ich habe gerade einen test mit 2 Millionen zufällig generierte Sätze Durchschnittliche Länge 22.5 Buchstaben mit einem sehr einfachen patricia trie-Implementierung, kam ich mit einer Weile zurück, und es dauerte 684 MB auf meinem Rechner. Ich habe auch gespeichert die zufällig generierte Sätze zu einem text-Datei und die Datei wurde 48 MB. Das scheint nicht allzu schlecht, vor allem, wenn man bedenkt, dass meine Implementierung ist nicht sehr Speicher effizient.
InformationsquelleAutor Justin Peel
Wenn die
re
Modul kann nicht tun Sie es schnell, du wirst es schwer haben, es zu tun alle schneller. So oder so werden Sie brauchen, um die gesamte Datei zu Lesen. Sie sollten erwägen, die Festsetzung der reguläre Ausdruck (können Sie?). Vielleicht etwas hintergrund auf, was Sie versuchen zu erreichen, auch.InformationsquelleAutor dlamotte
Könnten Sie versuchen, es zu tun die andere Weise herum...anstatt die Verarbeitung der text-Korpus von 2.000.000 mal (einmal für jedes Wort), es nur einmal. Für jedes einzelne Wort im Korpus, Schrittweite eine hash-Tabelle oder ähnliches zum speichern von die Anzahl der, das Wort. Ein einfaches Beispiel in pseudocode:
Könnten Sie in der Lage sein, es zu beschleunigen, durch Initialisierung der word_counts vor der Zeit mit der vollständigen Liste der Wörter, die dies nicht müssen, dass eine if-Anweisung...nicht sicher.
es gibt keinen Grund, Sie nicht für each_word_or_phrase, und kleben Sie die beiden im dict.
Ich bin in der Lage, um die Phrasen im Wörterbuch nach. Aber das corpus ist das gesuchte Wort durch das Wort, anstatt Satz für Satz. Wie kann ich die Suche über das corpus Satz und Betrag auf dem Wort, und wieder Suche für Satz.
InformationsquelleAutor davr
Als xyld gesagt, ich glaube nicht, dass man Sie schlagen kann die Geschwindigkeit der re-Modul, obwohl es helfen würde, wenn Sie veröffentlicht Ihre regexes und eventuell den code als gut. Ich kann nur hinzufügen, versuchen profiling vor der Optimierung. Sie können ganz überrascht, wenn Sie sehen, wo die meisten der Verarbeitung geht. Ich benutze hotshot zu Profil, meinen code und bin ganz zufrieden damit. Finden Sie eine gute Einführung in python-profiling-hier http://onlamp.com/pub/a/python/2005/12/15/profiling.html.
InformationsquelleAutor Nikwin
Wenn mit
re
ist nicht performant genug ist, verwenden Sie wahrscheinlichfindall()
oder finden die Spiele eins nach dem anderen manuell. Mit einem iterator kann damit es schneller geht:InformationsquelleAutor Max Shawabkeh
Läuft das, wir bekommen
Aber in jedem "Satz" explizit Hinzugefügt werden, der regex wird Ihren Tribut auf die Leistung -- die oben ist 50% langsamer als nur mit "\w+", durch meine grobe Messung.
Ich dachte, die zentrale Frage lautete: Kann jemand empfehlen, wie man über das Wort in der Zeichenfolge buffer. (Iterate-string-Puffer Wort für Wort) ?' Angesichts dieser Tatsache müssten Sie eine kleine state-machine oder solche, die im "für-w-in-itr:" Schleife übereinstimmen, Sätze, Wort für Wort. Ansonsten, ein komplizierter regex als nur "\w+" benötigt werden.
InformationsquelleAutor Kevin Little
Haben Sie als Blick auf die Natural Language Toolkit. Es beinhaltet viele nützliche Funktionen für die Arbeit mit einem Textkorpus, hat auch eine Coole FreqDist Klasse, verhält dict-like (hat Schlüssel) und eine Liste (slice).
InformationsquelleAutor Jason Humber