Anzahl gleicher Worte in einem Text

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
Python-Anfängerin
User
Beiträge: 2
Registriert: Dienstag 28. Oktober 2008, 20:41

Ich habe einen Text eingelesen und diesen nun als Liste aus Strings vorliegen. Jetzt hätte ich gerne die Verteilung der Wörter, also: "und" kommt viermal vor usw. Ich habe ein Beispielprogramm, wo sowas ähnliches mit einem Dictionary gemacht wird, kann das aber nicht übertragen, weil da die Länge des Strings, der gezählt werden soll vorgegeben ist (string=[i:i+2]). Gibt es vielleicht eine Schreibweise, dass der String bis zum nächsten Leerzeichen gehen soll? Das Ganze geht dann über eine for-Schleife mit if/else, aber ich häng jetzt echt an diesem (vlt. regulären?) Ausdruck.
Fabian Kochem
User
Beiträge: 36
Registriert: Mittwoch 5. April 2006, 14:11
Wohnort: Köln

Benutz doch einfach .split():

Code: Alles auswählen

kw = {}
arr = text.split(" ")
for item in arr:
    # dem dictionary hinzufügen bzw. hochzählen
Python-Anfängerin
User
Beiträge: 2
Registriert: Dienstag 28. Oktober 2008, 20:41

Oh Mann... Manchmal steht man echt auf dem Schlauch... Danke für die schnelle - und hilfreiche - Antwort!
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Und warum nicht einfach die count-Methode von Strings? (Text aus dem Vim-Artikel aus dem Python-Wiki)

Code: Alles auswählen

In [21]: text = u"""Vim ist der bekannteste Klon des eines der ältesten Editoren für Unices, vi.
Von elvis, nvi, WinVi und seinem Urvater vi unterscheidet er sich dadurch, dass er viele Verbesserungen
aufweist. Durch seinen Umfang und seine etwas andere Art ist er für den Anfänger oft sehr verwirrend,
da seine Bedienung sich stark von normalen Editoren wie etwa SciTE unterscheidet. Diese Seite will
jedoch nicht die Bediehnung von Vim lehren, denn dazu gibt es genügend andere Informationen im Internet,
wie auch den bei Vim mitgelieferten vimtutor. Vielmehr möchte diese Kurzanleitung aufzeigen, wie man Vim
dazu einsetzen kann effizienter in Python zu programmieren."""

In [22]: text.count("vi")
Out[22]: 6

In [23]: text.split(" ").count("vi")
Out[23]: 1
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

derdon hat geschrieben: (Text aus dem Vim-Artikel aus dem Python-Wiki)
Uhh sublime Propaganda :) Wobei sie natürlich durchaus gerechtfertigt ist :)
BlackJack

@derdon: "Einfach" die `count()`-Methode ist eine schlechte Idee weil ja nicht nur ein Wort gesucht werden soll, sondern ein Histogramm aller im Text vorkommenden Worte erstellt werden soll.

Ausserdem zählt Dein Ansatz auch alle Worte mit, in denen die Buchstabenfolge 'vi' vorkommt, und nicht nur 'vi' als eigenes Wort.

@Python-Anfängerin: Ich würde als Vorverarbeitung den Text in Kleinbuchstaben umwandeln und dann mit der `translate()`-Methode alles ausser Buchstaben durch Leerzeichen ersetzen.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

BlackJack hat geschrieben:@derdon: "Einfach" die `count()`-Methode ist eine schlechte Idee weil ja nicht nur ein Wort gesucht werden soll, sondern ein Histogramm aller im Text vorkommenden Worte erstellt werden soll.

Ausserdem zählt Dein Ansatz auch alle Worte mit, in denen die Buchstabenfolge 'vi' vorkommt, und nicht nur 'vi' als eigenes Wort.
Ich hab doch extra zwei verschiedene Aufrufe gezeigt, damit man sehen kann, dass einmal nach "vi" irgendwo im Text gesucht wird und einmal nach "vi" als Wort.

Code: Alles auswählen

In [61]: text.split(" ").index("vi")
Out[61]: 20

In [62]: text.split(" ")[20]
Out[62]: u'vi'
Edit: Typo
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@derdon Wie willst du damit sowas nachbauen?

Code: Alles auswählen

def count(s):
    counted = {}
    for word in s.split(' '):
        if word in counted:
            counted[word] += 1
        else:
            counted[word] = 1
    return counted
Verstanden wieso count keine gute Idee ist? ;)
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

[mod]collections#collections.defaultdict[/mod] ist hier hilfreich, wenn man als Factory int nimmt.

Gruß,
Manuel
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

@DasIch: sehr cooler Schnipsel! 8)
ichbinsisyphos
User
Beiträge: 120
Registriert: Montag 4. Juni 2007, 19:19

set() ist praktisch für histogramme. Damit kommen alle Einträge nur einmal vor.

* Eingelesen wird wahrscheinlich zeilenweise.
* Die Zeilen an Leerzeichen splitten und an neue Liste anhängen mit extend().
* Bereinigen, Satzzeichen raus, vielleicht Groß- in Kleinbuchstaben umwandeln, etc.
* Neue Liste ohne mehrfache Einträge mit list(set())
* Zählen wie oft jeder Eintrag im set in der Wörterliste vorkommt mit count().


Ich hab da noch eine blöde Frage: Wie liest man unicode-Text richtig ein?

p.s.: Das Wiki enthält eine Rechtschreibfehler: "Bediehnung".
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

ichbinsisyphos hat geschrieben:Ich hab da noch eine blöde Frage: Wie liest man unicode-Text richtig ein?
Schau mal ob dich [wiki]Von Umlauten, Unicode und Encodings[/wiki] weiterbringt.
ichbinsisyphos hat geschrieben:p.s.: Das Wiki enthält eine Rechtschreibfehler: "Bediehnung".
Dann melde dich doch einfach an und verbessere ihn. 8)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

mkallas hat geschrieben:
ichbinsisyphos hat geschrieben:p.s.: Das Wiki enthält eine Rechtschreibfehler: "Bediehnung".
Dann melde dich doch einfach an und verbessere ihn. 8)
Man braucht sich nichtmal anzumelden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@ichbinsisyphos: `set()` ist total unpraktisch für Histogramme eben gerade weil jedes Wort nur einmal drin vorkommen kann, ohne die Information *wie oft*. Ausserdem haben `set()`\s keine `count()`-Methode. Macht ja auch keinen Sinn, die könnte ja eh' nur 0 oder 1 liefern, und dafür kann man schon ``in`` verwenden.

Falls Du `str.count()` meintest: Überleg Dir doch mal was für besch*** Laufzeit der Algorithmus dadurch bekommt. Und da hat man wieder das bereits demonstrierte Problem, dass auch Treffer gezählt werden, die gar keine eigenständigen Worte sind.
ichbinsisyphos
User
Beiträge: 120
Registriert: Montag 4. Juni 2007, 19:19

BlackJack hat geschrieben:@ichbinsisyphos: `set()` ist total unpraktisch für Histogramme eben gerade weil jedes Wort nur einmal drin vorkommen kann, ohne die Information *wie oft*. Ausserdem haben `set()`\s keine `count()`-Methode. Macht ja auch keinen Sinn, die könnte ja eh' nur 0 oder 1 liefern, und dafür kann man schon ``in`` verwenden.

Falls Du `str.count()` meintest: Überleg Dir doch mal was für besch*** Laufzeit der Algorithmus dadurch bekommt. Und da hat man wieder das bereits demonstrierte Problem, dass auch Treffer gezählt werden, die gar keine eigenständigen Worte sind.
Aus dem set wird wieder eine Liste gemacht, die dann die Suchbegriffe enthält, gesucht selbst wird in der alten Liste.

Angenommen die Wörter sind mal bereinigt in einer Liste "woerter":

Code: Alles auswählen

woerterset = list(set(woerter))

histogram=[]
for i in woerterset:
    histogram.append([woerter.count(i), i])
Ich mach das inzwischen immer wenn ich keine mehrfachen Einträge will.

Die list(set())-Umwandlung wird die Laufzeit kaum beeinflussen, aber das Suchen in sehr langen Listen wird ineffizient, vielleicht sollt man gleich mit dicts arbeiten.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

ichbinsisyphos hat geschrieben:Die list(set())-Umwandlung wird die Laufzeit kaum beeinflussen, aber das Suchen in sehr langen Listen wird ineffizient, vielleicht sollt man gleich mit dicts arbeiten.
Mein Vorschlag:

Code: Alles auswählen

from collections import defaultdict

histogram = defaultdict(int)
for word in words:
    histogram[word] += 1

print histogram
Gruß,
Manuel
Antworten