Подсчет частоты слова и составление словаря из него

Я хочу взять каждое слово из текстового файла и посчитать частоту слов в словаре.

Пример: 'this is the textfile, and it is used to take words and count'

d = {'this': 1, 'is': 2, 'the': 1, ...} 

Я не так далеко, но я просто не вижу, как это сделать. Мой код до сих пор:

import sys

argv = sys.argv[1]
data = open(argv)
words = data.read()
data.close()
wordfreq = {}
for i in words:
    #there should be a counter and somehow it must fill the dict.

13 ответов

Решение

Если вы не хотите использовать collection.Counter, вы можете написать свою собственную функцию:

import sys

filename = sys.argv[1]
fp = open(filename)
data = fp.read()
words = data.split()
fp.close()

unwanted_chars = ".,-_ (and so on)"
wordfreq = {}
for raw_word in words:
    word = raw_word.strip(unwanted_chars)
    if word not in wordfreq:
        wordfreq[word] = 0 
    wordfreq[word] += 1

для более тонких вещей, посмотрите на регулярные выражения.

Хотя, используя Counter от collections библиотека, предложенная @Michael, является лучшим подходом, но я добавляю ответ только для того, чтобы улучшить ваш код (я думаю, что это будет ответом для нового ученика Python):

Из комментария в вашем коде кажется, что вы хотите улучшить свой код. И я думаю, что вы можете читать содержимое файла словами (хотя обычно я избегаю read() функция и использование for line in file_descriptor: вид кода).

Как words это строка, In для цикла, for i in words: переменная цикла i это не слово, а символ. Вы перебираете символы в строке вместо слов в строке words, Чтобы понять это уведомление, следующий фрагмент кода:

>>> for i in "Hi, h r u?":
...  print i
... 
H
i
,

h

r

u
?
>>> 

Поскольку итерация по строке char по символам вместо слова по словам - это не то, что вам нужно, чтобы перебирать слова по словам, вы должны отделить метод / функцию от строкового класса в Python.
str.split(str="", num=string.count(str)) Метод возвращает список всех слов в строке, используя str в качестве разделителя (разделяет все пробелы, если не указано), опционально ограничивая количество разбиений до num.

Обратите внимание на примеры кода ниже:

Трещина:

>>> "Hi, how are you?".split()
['Hi,', 'how', 'are', 'you?']

цикл с разделением:

>>> for i in "Hi, how are you?".split():
...  print i
... 
Hi,
how
are
you?

И это выглядит так, как вам нужно. Кроме слова Hi, так как split() по умолчанию разделены пробелами так Hi, хранятся в виде одной строки (и, очевидно), что вы не хотите. Посчитать частоту слов в файле.

Одним из хороших решений может быть использование регулярных выражений, но сначала, чтобы держать ответ простым, я отвечаю с replace() метод. Метод str.replace(old, new[, max]) возвращает копию строки, в которой вхождения старого были заменены на новые, при желании ограничение числа замен до макс.

Теперь проверьте приведенный ниже пример кода на предмет того, что я хочу предложить:

>>> "Hi, how are you?".split()
['Hi,', 'how', 'are', 'you?'] # it has , with Hi
>>> "Hi, how are you?".replace(',', ' ').split()
['Hi', 'how', 'are', 'you?'] # , replaced by space then split

цикл:

>>> for word in "Hi, how are you?".replace(',', ' ').split():
...  print word
... 
Hi
how
are
you?

Теперь, как посчитать частоту:

Одним из способов является использование Counter, как предложил @Michael, но использование вашего подхода, при котором вы хотите начать с пустого dict. Сделайте что-то вроде этого кода:

words = f.read()
wordfreq = {}
for word in .replace(', ',' ').split():
    wordfreq[word] = wordfreq.setdefault(word, 0) + 1
    #                ^^ add 1 to 0 or old value from dict 

Что я делаю?: потому что изначально wordfreq пусто, вы не можете назначить wordfreq[word] в первый раз (это поднимется ключевое исключение). так что я использовал метод setdefault dict.

dict.setdefault(key, default=None) похож на get(), но установит dict[key]=default если ключ еще не в dict. Итак, впервые, когда приходит новое слово, я установил его 0 в использовании setdefault затем добавьте 1 и назначить на тот же дикт.

Я написал эквивалентный код, используя с открытым вместо одного open,

with open('~/Desktop/file') as f:
    words = f.read()
    wordfreq = {}
    for word in words.replace(',', ' ').split():
        wordfreq[word] = wordfreq.setdefault(word, 0) + 1
print wordfreq

Это работает так:

$ cat file  # file is 
this is the textfile, and it is used to take words and count
$ python work.py  # indented manually 
{'and': 2, 'count': 1, 'used': 1, 'this': 1, 'is': 2, 
 'it': 1, 'to': 1, 'take': 1, 'words': 1, 
 'the': 1, 'textfile': 1}

С помощью re.split(pattern, string, maxsplit=0, flags=0)

Просто поменяйте цикл: for i in re.split(r"[,\s]+", words):, который должен произвести правильный вывод.

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

>>> re.findall(r'[\w]+', words) # manually indent output  
['this', 'is', 'the', 'textfile', 'and', 
  'it', 'is', 'used', 'to', 'take', 'words', 'and', 'count']

использовать для цикла как: for word in re.findall(r'[\w]+', words):

Как бы я написал код без использования read():

Файл:

$ cat file
This is the text file, and it is used to take words and count. And multiple
Lines can be present in this file.
It is also possible that Same words repeated in with capital letters.

Код является:

$ cat work.py
import re
wordfreq = {}
with open('file') as f:
    for line in f:
        for word in re.findall(r'[\w]+', line.lower()):
            wordfreq[word] = wordfreq.setdefault(word, 0) + 1

print wordfreq

Используемый lower() преобразовать верхнюю букву в нижнюю.

выход:

$python work.py  # manually strip output  
{'and': 3, 'letters': 1, 'text': 1, 'is': 3, 
 'it': 2, 'file': 2, 'in': 2, 'also': 1, 'same': 1, 
 'to': 1, 'take': 1, 'capital': 1, 'be': 1, 'used': 1, 
 'multiple': 1, 'that': 1, 'possible': 1, 'repeated': 1, 
 'words': 2, 'with': 1, 'present': 1, 'count': 1, 'this': 2, 
 'lines': 1, 'can': 1, 'the': 1}
from collections import Counter
t = 'this is the textfile, and it is used to take words and count'

dict(Counter(t.split()))
>>> {'and': 2, 'is': 2, 'count': 1, 'used': 1, 'this': 1, 'it': 1, 'to': 1, 'take': 1, 'words': 1, 'the': 1, 'textfile,': 1}

Или лучше с удалением пунктуации перед подсчетом:

dict(Counter(t.replace(',', '').replace('.', '').split()))
>>> {'and': 2, 'is': 2, 'count': 1, 'used': 1, 'this': 1, 'it': 1, 'to': 1, 'take': 1, 'words': 1, 'the': 1, 'textfile': 1}

Следующая строка берет строку, разбивает ее на список с помощью split(), for зацикливает список и подсчитывает частоту каждого элемента в предложении с помощью функции count () в Python. Слова i и их частота помещаются как кортежи в пустой список ls, а затем преобразуются в пары ключ и значение с помощью dict ().

sentence = 'this is the textfile, and it is used to take words and count'.split()
ls = []  
for i in sentence:

    word_count = sentence.count(i)  # Pythons count function, count()
    ls.append((i,word_count))       


dict_ = dict(ls)

print dict_

выход; {'и': 2, 'count': 1, 'used': 1, 'this': 1, 'is': 2, 'it': 1, 'to': 1, 'take': 1, ' слова ": 1", ": 1", "текстовый файл": 1}

sentence = "this is the textfile, and it is used to take words and count"

# split the sentence into words.
# iterate thorugh every word

counter_dict = {}
for word in sentence.lower().split():
# add the word into the counter_dict initalize with 0
  if word not in counter_dict:
    counter_dict[word] = 0
# increase its count by 1   
  counter_dict[word] =+ 1
#open your text book,Counting word frequency
File_obj=open("Counter.txt",'r')
w_list=File_obj.read()
print(w_list.split())
di=dict()
for word in w_list.split():


    if word in di:
        di[word]=di[word] + 1

    else:
        di[word]=1



max_count=max(di.values())
largest=-1
maxusedword=''
for k,v in di.items():
    print(k,v)
    if v>largest:
        largest=v
        maxusedword=k

print(maxusedword,largest)
wordList = 'this is the textfile, and it is used to take words and count'.split()
wordFreq = {}

# Logic: word not in the dict, give it a value of 1. if key already present, +1.
for word in wordList:
    if word not in wordFreq:
        wordFreq[word] = 1
    else:
        wordFreq[word] += 1

print(wordFreq)

Вы также можете использовать словари по умолчанию с типом int.

 from collections import defaultdict
 wordDict = defaultdict(int)
 text = 'this is the textfile, and it is used to take words and count'.split(" ")
 for word in text:
    wordDict[word]+=1

объяснение: мы инициализируем словарь по умолчанию, значения которого имеют тип int. Таким образом, значение по умолчанию для любого ключа будет 0, и нам не нужно проверять, присутствует ли ключ в словаре или нет. Затем мы разбиваем текст с пробелами на список слов. затем мы перебираем список и увеличиваем счетчик слов.

Вы также можете пойти с этим подходом. Но вам нужно сначала сохранить содержимое текстового файла в переменной в виде строки после чтения файла. Таким образом, вам не нужно использовать или импортировать какие-либо внешние библиотеки.

      s = "this is the textfile, and it is used to take words and count"

s = s.split(" ")
d = dict()
for i in s:
  c = ""
  if i.isalpha() == True: 
    if i not in d:
      d[i] = 1
    else:
      d[i] += 1
  else:
    for j in i:
      l = len(j)
      if j.isalpha() == True:
        c+=j    
    if c not in d:
      d[c] = 1
    else:
      d[c] += 1


print(d)

Результат:

Еще одна функция:

def wcount(filename):
    counts = dict()
    with open(filename) as file:
        a = file.read().split()
        # words = [b.rstrip() for b in a]
    for word in a:
        if word in counts:
            counts[word] += 1
        else:
            counts[word] = 1
    return counts

Мой подход заключается в том, чтобы сделать несколько вещей с нуля:

  1. Удалить знаки препинания из ввода текста.
  2. Составьте список слов.
  3. Удалить пустые строки.
  4. Перебирать список.
  5. Сделайте каждое новое слово ключом к словарю со значением 1.
  6. Если слово уже существует в качестве ключа, увеличьте его значение на единицу.

text = '''this is the textfile, and it is used to take words and count'''
word = '' #This will hold each word

wordList = [] #This will be collection of words
for ch in text: #traversing through the text character by character
#if character is between a-z or A-Z or 0-9 then it's valid character and add to word string..
    if (ch >= 'a' and ch <= 'z') or (ch >= 'A' and ch <= 'Z') or (ch >= '0' and ch <= '9'): 
        word += ch
    elif ch == ' ': #if character is equal to single space means it's a separator
        wordList.append(word) # append the word in list
        word = '' #empty the word to collect the next word
wordList.append(word)  #the last word to append in list as loop ended before adding it to list
print(wordList)

wordCountDict = {} #empty dictionary which will hold the word count
for word in wordList: #traverse through the word list
    if wordCountDict.get(word.lower(), 0) == 0: #if word doesn't exist then make an entry into dic with value 1
        wordCountDict[word.lower()] = 1
    else: #if word exist then increament the value by one
        wordCountDict[word.lower()] = wordCountDict[word.lower()] + 1
print(wordCountDict)

Другой подход:

text = '''this is the textfile, and it is used to take words and count'''
for ch in '.\'!")(,;:?-\n':
    text = text.replace(ch, ' ')
wordsArray = text.split(' ')
wordDict = {}
for word in wordsArray:
    if len(word) == 0:
        continue
    else:
        wordDict[word.lower()] = wordDict.get(word.lower(), 0) + 1
print(wordDict)
      Write a Python program to create a list of strings by taking input from the user and then create  a dictionary containing each string along with their frequencies. (e.g. if the list is [‘apple’,  ‘banana’, ‘fig’, ‘apple’, ‘fig’, ‘banana’, ‘grapes’, ‘fig’, ‘grapes’, ‘apple’] then output should be  {'apple': 3, 'banana': 2, 'fig': 3, 'grapes': 2}.  

lst = []
d = dict()
print("ENTER ZERO NUMBER FOR EXIT !!!!!!!!!!!!")
while True:
    user = input('enter string element :: -- ')
    if user == "0":
        break
    else:
        lst.append(user)
print("LIST ELEMENR ARE :: ",lst)
l = len(lst)
for i in range(l) :
    c = 0
    for j in range(l) :
        if lst[i] == lst[j ]:
            c += 1
    d[lst[i]] = c
print("dictionary is  :: ",d)

def play_with_words(ввод):

      input_split = input.split(",")
input_split.sort()
count = {}
for i in input_split:
    if i in count:
        count[i] += 1
    else:
        count[i] = 1

return count

input = "я, я, здесь, где, и, есть"

печать (play_with_words(ввод))

Другие вопросы по тегам