2010-07-30 15 views
6

Tengo una lista de aproximadamente 300 palabras y una gran cantidad de texto que quiero escanear para saber cuántas veces aparece cada palabra.Python: ¿la mejor/manera eficiente de encontrar una lista de palabras en un texto?

Estoy utilizando el módulo de re de pitón:

for word in list_word: 
    search = re.compile(r"""(\s|,)(%s).?(\s|,|\.|\))""" % word) 
    occurrences = search.subn("", text)[1] 

pero yo quiero saber si hay una manera más eficiente o más elegante de hacer esto?

+0

puede usar un wordbound en lugar de buscar espacios circundantes y signos de puntuación. '\ bWORD \ b' – mpen

+3

Si desea ir más allá de la frecuencia de las palabras y buscar en la clasificación de texto, puede consultar esto: http://streamhacker.com/2010/06/16/text-classification-sentiment- analysis-eliminar-baja-información-características/ – monkut

+0

¿Cuán ** enorme puede ser el texto si lo tiene en la memoria? – FMc

Respuesta

5

Si usted tiene una gran cantidad de texto, yo no usaría las expresiones regulares en este caso, sino simplemente el texto de división:

words = {"this": 0, "that": 0} 
for w in text.split(): 
    if w in words: 
    words[w] += 1 

palabras le dará la frecuencia para cada palabra

+0

Definitivamente más eficiente para escanear solo el texto una vez. El fragmento de código anterior simplemente parece no tener el control de que la palabra es una de las 300 "importantes". – pdbartlett

+0

@pdbartlett 'if w in words' hace esa comprobación. – Wilduck

+0

La división en espacios en blanco no siempre conducirá a resultados perfectos.Si necesita una división sofisticada, puede echar un vistazo a NLTK, que se sugiere a continuación. –

0

buscar en Google: Frecuencia pitón me da esta página como primer resultado: http://www.daniweb.com/code/snippet216747.html

que parece ser lo que estás buscando.

+0

Es sin pitonisa con todas estas expresiones regulares. La división en palabras separadas se logra mejor con str.split() que con la expresión regular personalizada –

+0

, tienes razón, si las funciones de cadenas de Python son suficientes, se deben usar en lugar de expresiones regulares. –

0

También puede dividir el texto en palabras y buscar en la lista resultante.

1

Intenta eliminar todos los signos de puntuación del texto y luego dividirlos en espacios en blanco. Después, simplemente hacer

for word in list_word: 
    occurence = strippedText.count(word) 

O si está utilizando Python 3.0 Creo que se podría hacer:

occurences = {word: strippedText.count(word) for word in list_word} 
+0

en 2.6 <= python <3.0 puedes hacer 'occurences = dict ((palabra, strippedText.count (palabra)) para la palabra en list_word)' – Wilduck

0

Si Python no es una necesidad, se puede usar awk

$ cat file 
word1 
word2 
word3 
word4 

$ cat file1 
blah1 blah2 word1 word4 blah3 word2 
junk1 junk2 word2 word1 junk3 
blah4 blah5 word3 word6 end 

$ awk 'FNR==NR{w[$1];next} {for(i=1;i<=NF;i++) a[$i]++}END{for(i in w){ if(i in a) print i,a[i] } } ' file file1 
word1 2 
word2 2 
word3 1 
word4 1 
0

Se me parece que el Natural Language Toolkit puede tener lo que necesita.

http://www.nltk.org/

+1

Específicamente el 'nltk.FreqDist' clase. –

0

tal vez se podría adaptar esta mi función de generador Multisearch.

from itertools import islice 
testline = "Sentence 1. Sentence 2? Sentence 3! Sentence 4. Sentence 5." 
def multis(search_sequence,text,start=0): 
    """ multisearch by given search sequence values from text, starting from position start 
     yielding tuples of text before sequence item and found sequence item""" 
    x='' 
    for ch in text[start:]: 
     if ch in search_sequence: 
      if x: yield (x,ch) 
      else: yield ch 
      x='' 
     else: 
      x+=ch 
    else: 
     if x: yield x 

# split the first two sentences by the dot/question/exclamation. 
two_sentences = list(islice(multis('.?!',testline),2)) ## must save the result of generation 
print "result of split: ", two_sentences 

print '\n'.join(sentence.strip()+sep for sentence,sep in two_sentences) 
Cuestiones relacionadas