Подсчитайте количество строк, в которых появляется каждое слово

#python #algorithm

#python #алгоритм

Вопрос:

У меня есть обучающий набор данных, который представляет собой массив numpy и имеет форму (4800,1). В нем есть столбец строк, и каждая строка соответствует текстам из другого электронного письма.

Я хочу создать словарь, который подсчитывает количество электронных писем (или количество строк), в которых появляется каждое слово, используя python. И в конечном итоге выберите только те слова, которые появляются как минимум в 10 электронных письмах. Я мог только понять, как подсчитать частоту появления слов во всем наборе данных, а не в количестве строк / электронных писем. Следующий код — это то, что у меня есть до сих пор

Вот пример того, как выглядит массив и что он должен выводить.

  [['red blue green green']
 ['red blue blue'] 
 ['red red red']]

  

вывод:

 {'red': 3, 'blue': '2', 'green': '1'}
  
 def vocab_dict(file):
    d = dict() 
    for row in xTrain:
        words = row.split(" ") 
        for word in words: 
            if word in d: 
                d[word] = d[word]   1
            else: 
                d[word] = 1
    d = dict((k, v) for k, v in d.items() if v >= 10)
    return d
  

Я застрял на том, как изменить приведенный выше код, который подсчитывает, сколько раз слово появляется во всем наборе данных, и сколько раз слово появляется в каждой строке (каждое электронное письмо).

Ответ №1:

Вы хотите выполнить итерацию по каждой строке и для каждого уникального слова в этом предложении добавить единицу к элементу dict, представляющему это слово. Вы можете получить уникальные слова, преобразовав список в a set .

 def vocab_dict(data):
    lines_count = {}
    for line in data:
        for word in set(line.split()):
            old_count = lines_count.get(word, 0)
            lines_count[word] = old_count   1
    return lines_count
  

dict.get() Функция возвращает значение этого ключа с значением по умолчанию 0, если ключ не существует. В качестве альтернативы вы могли бы использовать collections.defaultdict .

Тестирование:

 l = ['red blue green green', 'red blue blue', 'red red red']
vocab_dict(l)
# Out:  {'green': 1, 'blue': 2, 'red': 3}
  

Комментарии:

1. Спасибо! Ваше объяснение настолько ясно, что я сразу понял. это сработало отлично. Мне просто нужно было добавить строку перед возвратом, которая удаляет те, которые меньше 10 раз.

Ответ №2:

Допустим, у нас есть список строк l . Тогда мы можем сделать:

 from collections import Counter

word_lists = [text.split(" ") for text in l] # split into words
word_sets = [set(word_list) for word_list in word_lists] # make sets, discard duplicates

c = Counter()
for word_set in word_sets:
    c.update(word_set)
print(c)
  

c теперь будет содержать для каждого слова количество электронных писем, в которых это слово.

Ответ №3:

Один из вариантов — преобразовать words список в набор, чтобы он избавился от повторения. Вы можете сделать это следующим образом:

 [...]
for word in set(words):
    if word in d:
    [...]
  

Комментарии:

1. Это не сработает, поскольку words — это список полных текстов. Это приведет только к удалению повторяющихся электронных писем, а не повторяющихся слов.

2. @Anonymous1847 — words ссылается на список слов в каждой строке ( words = rows.split(' ') )

3. Я полагаю, вы имеете в виду words = row.split(' ') ?