2012-07-02 15 views
13

Tengo una cadena "Hello I am going to I with hello am". Quiero encontrar cuántas veces ocurre una palabra en la cadena. Ejemplo hola ocurre 2 veces. Intenté este enfoque que solo imprime caracteres -¿Cómo encontrar el conteo de una palabra en una cadena?

def countWord(input_string): 
    d = {} 
    for word in input_string: 
     try: 
      d[word] += 1 
     except: 
      d[word] = 1 

    for k in d.keys(): 
     print "%s: %d" % (k, d[k]) 
print countWord("Hello I am going to I with Hello am") 

Quiero aprender a encontrar el conteo de palabras.

+1

'' Hello' y hello' son iguales? –

+1

Dependiendo de su caso de uso, hay una cosa más que debe tener en cuenta: algunas palabras tienen sus significados que cambian según sus mayúsculas, como 'Polaco' y' Polaco'. Probablemente eso no le importe, pero vale la pena recordarlo. – DSM

+0

¿Podrías definir tu conjunto de datos más para nosotros, te preocuparán los signos de puntuación como 'I'll',' don't', etc. algunos de estos se mencionan en los comentarios a continuación. Y las diferencias en el caso? – Levon

Respuesta

31

Si usted quiere encontrar la cuenta de una palabra individual, sólo tiene que utilizar count:

input_string.count("Hello") 

Uso collections.Counter y split() hacer un recuento de todas las palabras:

from collections import Counter 

words = input_string.split() 
wordCount = Counter(words) 
+0

¿El módulo de colecciones forma parte de la instalación básica de python? – Varun

+0

@Varun sí lo es. –

+1

Estoy copiando parte de un comentario de @DSM que me queda ya que también utilicé 'str.count()' como mi solución inicial - esto tiene un problema ya que '" am ham ".count (" am ")' rendimiento 2 en lugar de 1 – Levon

3
from collections import * 
import re 

Counter(re.findall(r"[\w']+", text.lower())) 

Usando re.findall es más versátil que split, porque de lo contrario no se puede tener en cuenta las contracciones tales como "no" y "voy", etc.

Demo (usando el ejemplo):

>>> countWords("Hello I am going to I with hello am") 
Counter({'i': 2, 'am': 2, 'hello': 2, 'to': 1, 'going': 1, 'with': 1}) 

Si va a estar haciendo muchas de estas consultas, esto que solamente ocurre O (N) trabajar una vez, en lugar de O (N * # consultas) de trabajo.

+2

+1 por re. las soluciones 'split' no funcionarán con frases que contengan signos de puntuación. – georg

6

Counter from collections es su amigo:

>>> from collections import Counter 
>>> counts = Counter(sentence.lower().split()) 
1

Aquí está una al alter-, entre mayúsculas y minúsculas, el enfoque

sum(1 for w in s.lower().split() if w == 'Hello'.lower()) 
2 

Se ajusta mediante la conversión de la cadena y de destino en minúscula.

ps: Se encarga del problema con "am ham".count("am") == 2str.count() señalado por debajo @DSM también :)

+2

Sin embargo, el uso del recuento por sí mismo puede generar resultados inesperados: '" am ham ".count (" am ") == 2'. – DSM

+0

@DSM ... buen punto ... No estoy contento con esta solución de todos modos ya que es sensible a mayúsculas y minúsculas, buscando una alternativa en este momento ... – Levon

2

Considerando Hello y hello tan mismas palabras, independientemente de sus causas:

>>> from collections import Counter 
>>> strs="Hello I am going to I with hello am" 
>>> Counter(map(str.lower,strs.split())) 
Counter({'i': 2, 'am': 2, 'hello': 2, 'to': 1, 'going': 1, 'with': 1}) 
+0

Iría con 'Counter (strs.lower(). Split()) '. Reduce algunos de los gastos generales para un tiempo de ejecución más rápido – inspectorG4dget

+0

@ inspectorG4dget gracias :), ¡ah! Olvidé 'lower()' –

+1

¿No es esta solo la solución de Martijn Pieters ahora, sin embargo? – DSM

2

El vector de la los recuentos de ocurrencias de palabras se llaman bag-of-words.

Scikit-learn proporciona un buen módulo para calcularlo, sklearn.feature_extraction.text.CountVectorizer. Ejemplo:

import numpy as np 
from sklearn.feature_extraction.text import CountVectorizer 

vectorizer = CountVectorizer(analyzer = "word", \ 
          tokenizer = None, \ 
          preprocessor = None, \ 
          stop_words = None, \ 
          min_df = 0,   \ 
          max_features = 50) 

text = ["Hello I am going to I with hello am"] 

# Count 
train_data_features = vectorizer.fit_transform(text) 
vocab = vectorizer.get_feature_names() 

# Sum up the counts of each vocabulary word 
dist = np.sum(train_data_features.toarray(), axis=0) 

# For each, print the vocabulary word and the number of times it 
# appears in the training set 
for tag, count in zip(vocab, dist): 
    print count, tag 

de salida:

2 am 
1 going 
2 hello 
1 to 
1 with 

parte del código fue tomado de esta Kaggle tutorial on bag-of-words.

FYI: How to use sklearn's CountVectorizerand() to get ngrams that include any punctuation as separate tokens?

0

Usted puede usar la biblioteca de expresiones regulares de Python re para encontrar todos los partidos de la subcadena y devolver la matriz.

import re 

input_string = "Hello I am going to I with Hello am" 

print(len(re.findall('hello', input_string.lower()))) 

Lienzo:

2 
Cuestiones relacionadas