Извлечение нужных слов из нескольких текстовых файлов (Python 3.6)

У меня есть папка с ~ 100 000 текстовых файлов. Я пытаюсь прочитать все файлы и создать DataFrame с двумя идентификаторами столбцов и текстом. Для идентификатора я беру числа из своего имени файла, например, файл BL2334_uyhjghbvbvhf, я извлекаю все до подчеркивания, поэтому в этом примере мой идентификатор — BL2334. Перед созданием кадра данных я хотел бы извлечь только слова из Обнаруженного текста: ... Итак, в этом файле слово BUCK, NIP, Preerfal Deet Attracter.

Мой файл:

Id: 02398123-a642-4e3f-88a7
Type: LINE
Detected Text: BUCK
Confidence: 77.965172
Id: c85bbbe
Type: LINE
Detected Text: NIP
Confidence: 97.186539
Id: 28926a7a-78024c80-b9c5
Type: LINE
Detected Text: Preerfal Deet Attracter
Confidence: 47.749722

Мой код:

import os
import pandas as pd

path = r'C:\Users\example\Documents\MyFolder'

file_list = []

for (root, dirs, files) in os.walk(path, topdown=True):
        file_list.append([root + "\\" + file for file in files])
def flatten(file_list):
    result_list_files = []
    for element in file_list:
        if isinstance(element, str):
            result_list_files.append(element)
        else:
            for element_1 in flatten(element):
                result_list_files.append(element_1)
    return result_list_files 
result_flatten = flatten(file_list)

final_df = pd.DataFrame()

for file in result_flatten:
    temp_df = pd.DataFrame()
    id = file.split('\\')[-1].split('_')[0]
    temp_df['id'] = [id]
    temp_df['text'] = [open(file,encoding = "utf8").read()]
    final_df = pd.concat([final_df, temp_df], ignore_index = True)


Что не так с вашим кодом?

JeffUK 14.12.2020 15:57

Я получаю вывод с двумя идентификаторами столбцов и текстом. Это занимает много времени, и в моем текстовом столбце у меня есть все из моего файла, и мне нужны только слова из Detecte Text:

My80 14.12.2020 16:10
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
2
163
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

  • Чтобы получить только части Detected Text, я бы использовал регулярное выражение. Пример:

    import re
    
    text = """
    Id: 02398123-a642-4e3f-88a7
    Type: LINE
    Detected Text: BUCK
    Confidence: 77.965172
    Id: c85bbbe
    Type: LINE
    Detected Text: NIP
    Confidence: 97.186539
    Id: 28926a7a-78024c80-b9c5
    Type: LINE
    Detected Text: Preerfal Deet Attracter
    Confidence: 47.749722
    """
    
    pattern = re.compile(r"Detected Text: (.*)\n")
    match = pattern.findall(text)  # match becomes ['BUCK', 'NIP', 'Preerfal Deet Attracter']
    
  • Одна вещь, которая делает ваш код медленнее, заключается в том, что вы продолжаете выделять новые кадры данных, а затем объединяете их. Один из способов обойти это — сначала создать словарь с помощью key = id, value = text, а затем преобразовать его в DF с помощью метода from_dict: документация. Или вы можете использовать список таких кортежей (id, text), а затем просто:

    tuples = [
    ("id1", "some text")
    ("id2", "some other text")
    ...
    ]
    final_df = pd.DataFrame(tuples, columns=['id', 'text'])
    

Извините, я не уверен, что понимаю ваше решение. Перед final_df = pd.DataFrame() мне нужно создать словарь?

My80 14.12.2020 16:27

@DinkoJantoš Нет, в вашем for file in result_flatten: не создавайте df, а добавляйте в словарь или даже список кортежей ... что угодно. Затем только в конце цикла for вы конвертируете его во фрейм данных. Я обновил ответ примером.

Luca Angioloni 14.12.2020 16:28

Спасибо за помощь.

My80 14.12.2020 20:13
Ответ принят как подходящий

Просто расширив решение @Luca Angioioni, вы можете использовать что-то вроде:

import os
import re

data = {'id': [], 'text': []}

for (root, dirs, files) in os.walk(path):
    for file in files:
        data['id'].append(file.split('_')[0])
        with open(os.path.join(root, file)) as f:
            data['text'].append(re.findall('Detected Text: (.*)\n', f.read()))

df = pd.DataFrame(data)

где он вернет идентификатор со списком совпадений в text для каждой строки. Вы всегда можете использовать df.explode('text'), чтобы разбить совпадения на свои собственные строки с дублированными идентификаторами.


Если вы по какой-то причине не хотите использовать re, вы можете заменить последнюю строку на:

data['text'].append([line.split(':')[1].strip() for line in f if line.startswith('Detected Text')])

и это тоже должно работать.

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