2016-04-03 2 views
1

Ich versuche, eine große aufgeteilte Liste an die Funktion 'FreqDist' zu übergeben, um die häufigsten Wörter zu finden.Wie man nltk.FreqDist eine große gespaltene Liste oder Datei übergibt

I gespaltet die Liste Gurke wie folgt verwendet:

import nltk 
import cPickle as pickle 
import sys 
import os 
import itertools as it 
for no,i in enumerate(it.islice(it.count(), 3, 33+3, 3)): 
    if no == 0: 
     fil = tokens[0:i] 
    else: 
     fil = tokens[i-3+1:i+1] 

    file_name = "/tmp/words/text" + str(no+1) + '.p' 
    files = open(file_name, "wb") 
    pickle.dump(fil, files) 
    files.close() 

Jetzt würde ich die Dateien mit einer Klasse Operator wie folgt weitergeben möchte:

class Passer(object): 
    def __init__(self,path): 
     self.path = path 

    def __iter__(self): 
     return self 

    def __next__(self): 
     for fname in os.listdir(self.path): 
      with open(self.path + "/" + fname, "rb") as f: 
       fil = pickle.load(f) 
       yield fil 

passer = Passer(path="/tmp/words") 
words = nltk.FreqDist(passer) 

Leider ist es auf diese Weise tun Ich habe diesen Fehler:

TypeError: iter() returned non-iterator of type 'Passer' 

Hat jemand eine Idee, wie dieses Problem zu lösen?

+2

Iteratoren in Python 2 müssen die 'next'-Methode definieren (keine Unterstriche). – vaultah

+0

Das bedeutet, dass das, was ich getan habe, auf Python 3 arbeiten würde, oder? – alexmulo

+0

'__next__' würde auf Python 3 funktionieren, ja. In Python 3 gibt es jedoch kein cPickle. – vaultah

Antwort

0

Versuchen:

FreqDist(chain(*[word_tokenize(line) for line in open('in.txt')])) 

ZB:

[email protected]:~$ echo """This is a foo bar sentence 
> Not any more hahaha""" > in.txt 
[email protected]:~$ cat in.txt 
This is a foo bar sentence 
Not any more hahaha 
[email protected]:~$ python 
Python 2.7.11 (default, Dec 15 2015, 16:46:19) 
[GCC 4.8.4] on linux2 
fType "help", "copyright", "credits" or "license" for more information. 
>>> from nltk import FreqDist 
>>> from itertools import chain 
>>> from nltk import word_tokenize 
>>> FreqDist(chain(*[word_tokenize(line) for line in open('in.txt')])) 
FreqDist({'a': 1, 'bar': 1, 'sentence': 1, 'This': 1, 'is': 1, 'hahaha': 1, 'Not': 1, 'foo': 1, 'any': 1, 'more': 1}) 
+0

Dies ist nur eine Problemumgehung. Vielleicht sollten Sie erklären, wie Sie auch den 'TypeError' loswerden können? – vaultah

+0

Hallo Alvas vielen Dank für Ihre Antwort. Es hat mir geholfen, diesen Generator zu machen: 'nltk.FreqDist (it.chain ([Wort für Wort in pickle.load (open (Dateiname)) für Dateiname in os.listdir ("/ tmp/words /")])) ". Es funktioniert sehr gut! Gibt es eine Möglichkeit, etwas ähnliches mit einer Klasse und einer __iter__ Funktion zu tun? Nochmals vielen Dank – alexmulo

+0

Ich denke, es könnte ein Overkill sein, Ihre eigene Klasse zu erstellen, um einen Korpus zu lesen. Sehen Sie sich die bereits in NLTK codierten Korpusleser an. Diese könnten Ihnen helfen, https://github.com/nltk/nltk/tree/develop/nltk/corpus/reader – alvas

0

ich den folgenden Text in 11 Beize Dateien gespeichert:

text = 'The European Union’s plan to send refugees fleeing Syria’s civil war back to Turkey en masse could be illegal, a top UN official has said, as concerns mounted that Greece,Greece2' 

Das Verzeichnis wird Wörter genannt (path =/tmp/Wörter) und es gibt 11 filles namens testo1, testo2 und so weiter. Nun fand ich das richtige Verständnis, um mein Ziel zu erreichen:

nltk.FreqDist([word for f in os.listdir("/tmp/words/") for word in pickle.load(open("/tmp/words/"+f))]) 

Nun scheint es, dass alles funktioniert, aber frage ich mich, ob dies den FreqDist Schritt für Schritt füttern oder wenn er die Liste wird geladen ersten und als verarbeitet es. Weil meine Idee war, die Dateien Schritt für Schritt zu laden und zu verarbeiten, ohne sie alle einmal zu laden, um Speicher zu sparen.

Danke nochmal für die Hilfe.

Verwandte Themen