2014-12-06 5 views
0

Мне нужно отображать 10 наиболее часто встречающихся слов в текстовом файле, от самого частого до наименьшего, а также от количества использованных им времени. Я не могу использовать словарь или функцию счетчика. До сих пор у меня есть это:10, наиболее часто встречающиеся слова в строке Python

import urllib 
cnt = 0 
i=0 
txtFile = urllib.urlopen("http://textfiles.com/etext/FICTION/alice30.txt") 
uniques = [] 
for line in txtFile: 
    words = line.split() 
    for word in words: 
     if word not in uniques: 
      uniques.append(word) 
for word in words: 
    while i<len(uniques): 
     i+=1 
     if word in uniques: 
      cnt += 1 
print cnt 

Теперь я думаю, что я должен искать каждое слово в массиве «уников» и посмотреть, сколько раз она повторяется в этом файле, а затем добавить, что в другой массив, который подсчитывает экземпляр каждого слова. Но это то место, где я застрял. Я не знаю, как это сделать.

Любая помощь будет оценена по достоинству. Спасибо

+4

Это звучит как проблема домашней работы – Greg

+1

@Greg Это точно. Однако SO не дискриминирует домашние задания, поэтому я не вижу проблемы? –

+1

В чем проблема с кодом? Что не работает? Какие сообщения об ошибках вы получаете? Или вы просто хотите, чтобы кто-то написал код для вас? –

ответ

0

Лично я сделал бы свою собственную реализацию collections.Counter. Я предполагаю, что вы знаете, как работает этот объект, но если я не буду резюмировать:

text = "some words that are mostly different but are not all different not at all" 

words = text.split() 

resulting_count = collections.Counter(words) 
# {'all': 2, 
# 'are': 2, 
# 'at': 1, 
# 'but': 1, 
# 'different': 2, 
# 'mostly': 1, 
# 'not': 2, 
# 'some': 1, 
# 'that': 1, 
# 'words': 1} 

Мы можем, конечно, что-то на основе частоты, используя аргумент key ключевого слова sorted и возвращать первые 10 пунктов в этом списке , Однако это не очень помогает вам, потому что у вас нет Counter. Я оставлю эту часть как упражнение для вас и покажу вам, как вы можете реализовать Counter как функцию, а не объект.

def counter(iterable): 
    d = {} 
    for element in iterable: 
     if element in d: 
      d[element] += 1 
     else: 
      d[element] = 1 
    return d 

Не сложно, на самом деле. Пройдите через каждый элемент итерабельного. Если этот элемент НЕ находится в d, добавьте его в d со значением 1. Если он находится в d, увеличьте это значение. Это легко выражается:

def counter(iterable): 
    d = {} 
    for element in iterable: 
     d.setdefault(element, 0) += 1 

Обратите внимание, что в вашем случае использования, вы, вероятно, хотите, чтобы вырезать знаки препинания и, возможно, casefold все это (так что someword получает подсчитываются так же, как Someword, а не в виде двух отдельных слов). Я оставлю это и вам, но я укажу, что str.strip принимает аргумент о том, что нужно вырезать, а string.punctuation содержит всю пунктуацию, в которой вы, скорее всего, понадобятся.

+0

Благодарим за помощь. Как реализовать эту функцию? Я позабочусь о оставшихся деталях, таких как сортировка и удаление, мне просто нужна эта часть – KevinKZ

+0

@KevinKZ Ну, файловый объект уже является итератором для его строк. Я бы сделал функцию генератора, которая берет линии и разделяет пробелы, снимая по мере необходимости и передавая все это в функцию 'counter'. Что-то вроде 'words = (word.strip (однако) для строки в файле_obj для слова в строке.split())' 'count =' counter (words) ' –

+0

Вы не хотите запускать счетчик со значением по умолчанию 1, но 0. Расширенная версия в порядке, но одна, использующая setdefault, должна начинать с 0 – chapelo

2

Вы на правильном пути. Обратите внимание, что этот алгоритм довольно медленный, потому что для каждого уникального слова он выполняет итерацию по всем словам. Гораздо более быстрый подход без хеширования предполагает создание trie.

# The following assumes that we already have alice30.txt on disk. 
# Start by splitting the file into lowercase words. 
words = open('alice30.txt').read().lower().split() 

# Get the set of unique words. 
uniques = [] 
for word in words: 
    if word not in uniques: 
    uniques.append(word) 

# Make a list of (count, unique) tuples. 
counts = [] 
for unique in uniques: 
    count = 0    # Initialize the count to zero. 
    for word in words:  # Iterate over the words. 
    if word == unique: # Is this word equal to the current unique? 
     count += 1   # If so, increment the count 
    counts.append((count, unique)) 

counts.sort()   # Sorting the list puts the lowest counts first. 
counts.reverse()   # Reverse it, putting the highest counts first. 
# Print the ten words with the highest counts. 
for i in range(min(10, len(counts))): 
    count, word = counts[i] 
    print('%s %d' % (word, count)) 
0
from string import punctuation #you will need it to strip the punctuation 

import urllib 
txtFile = urllib.urlopen("http://textfiles.com/etext/FICTION/alice30.txt") 

counter = {} 

for line in txtFile: 
    words = line.split() 
    for word in words: 
     k = word.strip(punctuation).lower() #the The or you You counted only once 
     # you still have words like I've, you're, Alice's 
     # you could change re to are, ve to have, etc... 
     if "'" in k: 
      ks = k.split("'") 
     else: 
      ks = [k,] 
     #now the tally 
     for k in ks: 
      counter[k] = counter.get(k, 0) + 1 
#and sorting the counter by the value which holds the tally 
for word in sorted(counter, key=lambda k: counter[k], reverse=True)[:10]: 
    print word, "\t", counter[word] 
0
import urllib 
import operator 
txtFile = urllib.urlopen("http://textfiles.com/etext/FICTION/alice30.txt").readlines() 
txtFile = " ".join(txtFile) # this with .readlines() replaces new lines with spaces 
txtFile = "".join(char for char in txtFile if char.isalnum() or char.isspace()) # removes everything that's not alphanumeric or spaces. 

word_counter = {} 
for word in txtFile.split(" "): # split in every space. 
    if len(word) > 0 and word != '\r\n': 
     if word not in word_counter: # if 'word' not in word_counter, add it, and set value to 1 
      word_counter[word] = 1 
     else: 
      word_counter[word] += 1 # if 'word' already in word_counter, increment it by 1 

for i,word in enumerate(sorted(word_counter,key=word_counter.get,reverse=True)[:10]): 
    # sorts the dict by the values, from top to botton, takes the 10 top items, 
    print "%s: %s - %s"%(i+1,word,word_counter[word]) 

выход:

1: the - 1432 2: and - 734 3: to - 703 4: a - 579 5: of - 501 6: she - 466 7: it - 440 8: said - 434 9: I - 371 10: in - 338

Этот метод гарантирует, что только буквенно-цифровые и пространства в счетчике. Это не важно.

0

Вы также можете сделать это через кадры данных pandas и получить результат в удобной форме в виде таблицы: «word-its freq». приказал.

def count_words(words_list): 
words_df = pn.DataFrame(words_list) 
words_df.columns = ["word"] 
words_df_unique = pn.DataFrame(pn.unique(words_list)) 
words_df_unique.columns = ["unique"] 
words_df_unique["count"] = 0 
i = 0 
for word in pn.Series.tolist(words_df_unique.unique): 
    words_df_unique.iloc[i, 1] = len(words_df.word[words_df.word == word]) 
    i+=1 
res = words_df_unique.sort_values('count', ascending = False) 
return(res) 
+0

Таким образом, у вас будет блок данных, вы можете выбрать 10 наиболее часто встречающихся слов, используя df.head (10) или 10 наиболее редких с df.tail (10) –

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