Как получить очищенные данные из зашумленного tsv-файла с помощью регулярного выражения?

Мне нужно очистить данные, хранящиеся в tsv, в фрейме данных, используя регулярное выражение, для справки данные выглядят так

ps8trw17rlo16s  dh7r1wjixjse72  Theoretical movements expensive. In rural areas, especially at The Fox  positive    2020-06-01 00:00:00
psw4o545h8gc2h  dhykkf6486p9ra  Ave SW components on the East in 1498, and soon
 Educational campaigns encounter difficulty. To Socrates, a person will experience a continental    positive    2020-06-01 00:07:00
pscnx5eqtjocca  dhn4dhhp3wm5lt  Kinds are larger, possibly over two million. The country is the city's average. Hollywood    Fril Functional four national
 Pp. Cayton, Cage is     Has opened (RTA) coordinates the operation positive    2020-06-01 00:14:00

данные искажены по своей природе, и мне приходится разделить данные на pid, uid, text, предсказание, datetile

Это мой код

# Sample file path
input_file_path = 'logs.tsv'
output_file_path = 'cleaned_logs.txt'

# Read the malformed TSV file and write it to a text file
with open(input_file_path, 'r', encoding='utf-8') as infile, open(output_file_path, 'w', encoding='utf-8') as outfile:
    for line in infile:
        outfile.write(line)
import pandas as pd
import re

# Define regex patterns for each column
patterns = {
    'pid': r'[A-Za-z0-9]+',  # Matches a word (alphanumeric characters)
    'uid': r'[A-Za-z0-9]+',  # Matches a word (alphanumeric characters)
    'text': r'([^\t]+)\t([^\t]+)\t([^\t]+)',  # Matches the entire text (paragraph)
    'prediction': r'(positive|negative)',  # Matches 'positive' or 'negative'
    'datetime': r'[0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,3})?'  # Matches datetime format 'YYYY-MM-DD HH:MM:SS'
}

# Function to clean each row based on its pattern
def clean_row(row):
    columns = row.split('\t')
    if len(columns) != 5:
        return [None, None, None, None, None]  # Return a list of Nones if the row is malformed
    
    cleaned_data = []
    cleaned_data.append(re.match(patterns['pid'], columns[0]).group(0) if re.match(patterns['pid'], columns[0]) else None)
    cleaned_data.append(re.match(patterns['uid'], columns[1]).group(0) if re.match(patterns['uid'], columns[1]) else None)
    cleaned_data.append(re.match(patterns['text'], columns[2]).group(0) if re.match(patterns['text'], columns[2]) else None)
    cleaned_data.append(re.match(patterns['prediction'], columns[3]).group(0) if re.match(patterns['prediction'], columns[3]) else None)
    cleaned_data.append(re.match(patterns['datetime'], columns[4]).group(0) if re.match(patterns['datetime'], columns[4]) else None)
    return cleaned_data

# Read the cleaned text file
with open(output_file_path, 'r', encoding='utf-8') as file:
    rows = file.readlines()

# Initialize a list to collect cleaned rows
cleaned_rows = []

# Process each row with its corresponding pattern
for row in rows:
    row = row.strip()  # Remove leading/trailing whitespace
    cleaned_row = clean_row(row)
    cleaned_rows.append(cleaned_row)

# Convert the cleaned rows to a DataFrame
df = pd.DataFrame(cleaned_rows, columns=['pid', 'uid', 'text', 'prediction', 'datetime'])

# Display the DataFrame
print(df)

# Optionally, save the DataFrame to a CSV file
df.to_csv('cleaned_logs.csv', index=False)


Какую строку регулярного выражения мне следует использовать для решения такой проблемы?

Я пробовал идти построчно, но мне все равно не удалось захватить весь текст.

Каким образом данные могут быть искажены? На первый взгляд то, что вы представили в вопросе, соответствует вашим шаблонам.

Nick 18.05.2024 07:33

Почему вам нужно использовать регулярное выражение? Кроме того, если содержимое файла такое, как показано в вопросе, то по определению это не TSV.

SIGHUP 18.05.2024 09:52
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не думаю, что ваши данные представляют собой действительный TSV. Кажется, что некоторые «записи» разбиты на несколько строк.

Также кажется, что запись ограничена PID (слева) и парой дата/время (справа).

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

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

import pandas as pd
from collections import defaultdict

FMT = "%Y-%m-%d %H:%M:%S"

with open("foo.tsv") as fd:
    tokens = fd.read().split()
    data = defaultdict(list)
    k = 0
    for i in range(3, len(tokens)):
        try:
            dt = pd.to_datetime(" ".join(tokens[i-1:i+1]), format=FMT)
            data["pid"].append(tokens[k])
            data["uid"].append(tokens[k + 1])
            data["text"].append(" ".join(tokens[k + 2 : i - 2]))
            data["prediction"].append(tokens[i - 2])
            data["datetime"].append(dt)
            k = i + 1
        except ValueError:
            pass

    df = pd.DataFrame(data)

    print(df)

Выход:

              pid             uid                                               text prediction            datetime
0  ps8trw17rlo16s  dh7r1wjixjse72  Theoretical movements expensive. In rural area...   positive 2020-06-01 00:00:00
1  psw4o545h8gc2h  dhykkf6486p9ra  Ave SW components on the East in 1498, and soo...   positive 2020-06-01 00:07:00
2  pscnx5eqtjocca  dhn4dhhp3wm5lt  Kinds are larger, possibly over two million. T...   positive 2020-06-01 00:14:00

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