2012-07-02 3 views
13

У меня есть строка «Hello I am going to I with hello am». Я хочу узнать, сколько раз в строке происходит слово. Пример hello происходит 2 раза. Я пробовал этот подход, который печатает только символы:Как найти количество слов в строке?

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") 

Я хочу узнать, как найти количество слов.

+1

'' Hello' и hello' такие же? –

+1

В зависимости от вашего прецедента есть еще одна вещь, которую вам, возможно, потребуется рассмотреть: некоторые слова имеют свои значения в зависимости от их капитализации, например, «польский» и «польский». Вероятно, это не имеет значения для вас, но это стоит вспомнить. – DSM

+0

Не могли бы вы определить, какой набор данных больше для нас, вы будете беспокоиться о пунктуации, например, в 'I'll',' don't' и т. Д. Некоторые из них приведены в комментариях ниже. И различия в случае? – Levon

ответ

31

Если вы хотите, чтобы найти количество отдельного слова, просто используйте count:

input_string.count("Hello") 

Использование collections.Counter и split() подсчитывать все слова:

from collections import Counter 

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

Является ли сборником частью базовой установки python? – Varun

+0

@Varun да есть. –

+1

Я копирую часть комментария @DSM для меня, так как я также использовал 'str.count()' в качестве моего начального решения - это проблема, поскольку '' am ham ".count (" am ")' будет выход 2, а не 1 – Levon

3
from collections import * 
import re 

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

Использование re.findall является более универсальным, чем split, потому что в противном случае вы не можете принять во внимание сокращений, таких как «не» и «я буду» и т.д.

Demo (используя пример):

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

Если вы планируете делать многие из этих запросов, то это будет только делать O (N) работают один раз, а не O (N * # запросов) работу.

+2

+1 для re. Решения 'split' не будут работать с фразами, содержащими пунктуации. – georg

1

Настоящий аль

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

Он соответствует преобразованию строки и цели в нижний регистр.

пс: Заботится о "am ham".count("am") == 2 проблемы с str.count() указал @DSM внизу тоже :)

+2

Использование подсчета само по себе может привести к неожиданным результатам: '' am ham '.count ("am") == 2'. – DSM

+0

@ DSM .. хорошая точка .. Я так и не доволен этим решением, так как он чувствителен к регистру, глядя на альтернативу прямо сейчас ... – Levon

2

Учитывая Hello и hello как же словами, независимо от их дел:

>>> 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

Я бы пошел с 'Counter (strs.lower(). Split()) '. Уменьшает некоторые накладные расходы для более быстрой работы – inspectorG4dget

+0

@ inspectorG4dget thanks :), ах! Я забыл 'lower()' –

+1

Разве это не решение Martijn Pieters? – DSM

2

Вектор число совпадений слов называется bag-of-words.

Scikit-learn предоставляет хороший модуль для его вычисления, sklearn.feature_extraction.text.CountVectorizer. Пример:

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 

Выход:

2 am 
1 going 
2 hello 
1 to 
1 with 

Часть кода была взята из этого Kaggle tutorial on bag-of-words.

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

0

Вы можете использовать регулярное выражение библиотеки Python re найти все матчи в подстроку и возвращает массив.

import re 

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

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

Печать:

2 
Смежные вопросы