Специалист в области управления и информатики в технических системах.
Data Engeneer, IT... · 17 авг 2022
Трюки с Pandas. Как найти и удалить в текстовом столбце лишние символы
Иногда возникает ситуация, когда в процессе очистки текстовых данных необходимо найти ненужные символы и удалить их из набора данных.
В качестве примера рассмотрим набор данных новостей на русском языке из различных источников которые необходимо отчистить от различных символов.
Подключим Google Disk:
# Подключим диск Google Drive
from google.colab import drive
drive.mount('/content/drive')
Импортируем необходимые модули:
import pandas as pd
import chardet
import re
Прежде чем производить какие-либо манипуляции с текстовыми данными важно определить используемую кодировку. Это поможет избежать проблем с представлением данных в дальнейшем. Для этого считаем первые 10000 байт файла и попробуем определить кодировку:
data_homework_path = "/content/drive/MyDrive/Data/русские_новости_тональность.json"
bytes_num = 10000
# посмотрим на первые десять тысяч байтов, чтобы определить кодировку символов
with open(data_homework_path, 'rb') as rawdata:
result = chardet.detect(rawdata.read(bytes_num))
# проверим, какая может быть кодировка символов
print("С вероятностью", str(result['confidence'] * 100) + "%", "используемая кодировка символов", str(result['encoding']).upper())
print(result)
Вывод:
С вероятностью 99.0% используемая кодировка символов UTF-8
{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}
Зная кодировку, мы можем загрузить данные в Pandas Dataframe:
# Загрузим данные отбросив столбец `id`, Pandas сгенерирует новый аналогичный столбец сам.
# При загрузке данных в Pandas Dataframe нет необходимости указывать кодировку файла UTF8, она используется по умолчанию.
data = pd.read_json(data_homework_path).drop('id', axis=1)
При использовании кодировки UTF8 в современном русском тексте могут встретится различные не русские символы, например знак доллара, эмоджи и т. д.
Посмотрим на наши данные:
data.iloc[[15,16]]
Действительно, не русских символов хоть отбавляй. Проверим, какие еще символы используются в тестах новостей кроме заглавных и строчных русских букв и символа пробела:
# Функция возвращяющая dataframe с некорректными символами содержащимися в столбце
def get_illegal_characters(df, column_name, legitimate_characters, encoding='utf8', DEBUG=False):
# получим все не легитимные символы из датафрейма
result = df[column_name].str.extractall(legitimate_characters)
# Решим проблему с повторениями.
result = result[0].unique()
result = pd.DataFrame(result)
# Добавим столбец с hex кодировкой символов.
result['hex_code'] = result[0].str.encode(encoding)
# Дадим адекватные имена столбцам.
result.rename(columns={0: 'character'}, inplace=True)
if (DEBUG):
print("Найдено", result.shape[0], "уникальных символов не подходящих под заданный шаблон.")
print("Найдены следующие символы:\n", result)
return result
# Шаблон "легитимных символов". Использование этих символов допустимо в русском языке.
# Естественно символ пробела мы тоже оставим, иначе наши слова "склеятся".
legitimate_characters = "([^а-яёА-ЯЁ ])"
# Имя столбца, который необходимо проверить
column_name = 'text'
bad_symbols = get_illegal_characters(data, column_name, legitimate_characters)
bad_symbols
Вывод:
Надо же, начиная со 166 символа начинаются иероглифы. На 227 позиции находится эмодзи. Это точно то, что нам не нужно. Удалим ненужные нам символы из текста новостей:
# Создадим шаблон из найденных ненужных символов.
# Ненужные символы необходимо предварительно экранировать, затем обьединить
# в список.
template = '|'.join(map(re.escape, bad_symbols['character']))
# Удалим ненужные символы из новостей.
data['text'] = data['text'].str.replace(template, '', regex=True, flags=re.UNICODE)
# Посмотрим на результат
data.iloc[[15,16]]
Вывод:
Отлично, все ненужные cимволы включая эмодзи, пунктуацию и так далее - удалены.