Добавить несколько объектов Counter () и преобразовать в фрейм данных - PullRequest
0 голосов
/ 10 октября 2018

Я хотел бы найти частоты слов в списке зарезервированных слов в нескольких файлах .txt в виде фрейма данных pandas.Я использую объекты collection.Counter (), и если определенное слово не появляется в тексте, значение этого слова (ключа) в Counter () равно нулю.

В идеале, результатом является кадр данных, где каждая строка соответствует каждому .txt-файлу, заголовки столбцов соответствуют зарезервированным словам, а запись в строке i столбца j соответствует частоте j-го слова вi-й .txt файл.

Вот мой код, но проблема в том, что объекты Counter () не добавляются в смысле словаря с несколькими значениями для каждого ключа (или зарезервированного слова), а суммируются вместо:

for filepath in iglob(os.path.join(folder_path, '*.txt')):
    with open(filepath) as file:
        cnt = Counter()
        tokens = re.findall(r'\w+', file.read().lower())
        for word in tokens:
            if word in mylist:
                cnt[word] += 1
            for key in mylist:
                if key not in cnt:
                    cnt[key] = 0
        dictionary = defaultdict(list)
        for key, value in cnt.items():
            dictionary[key].append(value)
    print(dictionary)

Любая подсказка будет высоко оценена!

1 Ответ

0 голосов
/ 31 октября 2018

Вам необходимо создать словарь для кадра данных перед циклом, а затем скопировать / добавить значения Counter каждого текстового файла.

#!/usr/bin/env python3
import os
import re
from collections import Counter
from glob import iglob


def main():
    folder_path = '...'
    keywords = ['spam', 'ham', 'parrot']

    keyword2counts = {keyword: list() for keyword in keywords}
    for filename in iglob(os.path.join(folder_path, '*.txt')):
        with open(filename) as file:
            words = re.findall(r'\w+', file.read().lower())

        keyword2count = Counter(word for word in words if word in keywords)

        for keyword in keywords:
            keyword2counts[keyword].append(keyword2count[keyword])

    print(keyword2counts)


if __name__ == '__main__':
    main()

Проверка наличия элемента в банке listбыть значительно медленнее, чем делать тот же тест для элементов в set.Поэтому, если это слишком медленно, вы можете использовать set для keywords или дополнительный только для теста.

И collections.OrderedDict до Python 3.7 (или CPython 3.6), если порядокстолбцы актуальны.

...