Python: замена нескольких элементов в файле - PullRequest
1 голос
/ 29 января 2020

Мне дали два текстовых файла с данными. Файл A содержал неверные данные, а файл B содержал правильные данные. Используя библиотеку Pandas, я смог найти несоответствия (~ 17000!). Теперь я хочу изменить файл A и заменить неправильное поле на правильное. Например,

File A (Incorrect)
Name = PARAMETER_1
Field_1 = a
Field_2 = b
Field_3 = c
Field_4 = WRONG1!

Name = PARAMETER_2
Field_1 = a
Field_2 = b
Field_3 = c
Field_4 = WRONG2!
etc.

следует заменить на:

File A (Correct)
Name = PARAMETER_1
Field_1 = a
Field_2 = b
Field_3 = c
Field_4 = CORRECT1!

Name = PARAMETER_2
Field_1 = a
Field_2 = b
Field_3 = c
Field_4 = CORRECT2!
etc.

Датафрейм выглядел примерно так:

   Parameter    Wrong    Correct    Match
0  PARAMETER_1  WRONG1!  CORRECT1!  False
1  PARAMETER_2  WRONG2!  CORRECT2!  False
  etc.

Я пытался сделать это с помощью a для l oop:

# read file A
with open(file_A_loc, 'r') as f:
        data_text = f.read()

for row in df.itertuples():
    new = re.sub(r'(?<=Name = ' + row[1] + r')([\w\W]+?Field_4 = )([\w]+)', r'\g<1>'+row[3], data_text, flags=re.I)

Это, как вы можете себе представить, заняло очень много времени (размер файла A составляет ~ 40-50 МБ). Любые предложения, чтобы ускорить этот процесс? Я просмотрел страницы stackoverflow перед отправкой вопроса и нашел ссылки на использование словаря. Я пытался использовать этот метод, но получил KeyError:

def foo(rep_dict, text): 

  # Create a regular expression  from the dictionary keys
    regex = re.compile('|'.join(rep_dict.keys()), flags=re.I)

  # For each match, look-up corresponding value in dictionary
    return regex.sub(lambda x: rep_dict[x.group(0)], text)

rep_dict = {
            r'(?<=Name = ' + 'PARAMETER_1' + r')([\w\W]+?Field_4 = )([\w]+)':r'\g<1>'+'CORRECT1!',
            r'(?<=Name = ' + 'PARAMETER_2' + r')([\w\W]+?Field_4 = )([\w]+)':r'\g<1>'+'CORRECT2!'
           }
bar = foo(rep_dict, data_text)
print(bar)

PS Прошу прощения за любые нарушения уценки с моей стороны.

ОБНОВЛЕНИЕ: Я пытался реализовать методы здесь и здесь . Тем не менее, все еще очень долго. По крайней мере, это решило ошибку KeyError, которую я получал ранее.

1 Ответ

0 голосов
/ 31 января 2020

Я решил свою проблему, используя следующий базовый c алгоритм:

  1. Захватите все в файле A, используя re.findall, и получите список в форме: ['Name = PARAMETER1 ... Field_4 = WRONG1 ',' Name = PARAMETER2 ... Field_4 = WRONG2 ', ...]

  2. Используйте Pandas, чтобы получить различия между файлом A и файл B.

  3. Итерация по строкам с использованием df.itertuples. Используйте индексы в Pandas фрейме данных, чтобы применить re.sub к указанному c элементу в списке, полученном на шаге 1.

Этот метод, в моем случае использования, для запуска требуется около 9-10 секунд!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...