2025, Oct 30 23:17
Очистка текста в pandas: как правильно использовать str.replace с regex=True
Как очистить текст в pandas: почему Series.str.replace без regex=True не меняет строки, как удалить пунктуацию, сохранить пробелы и не-ASCII буквы. Примеры.
Очистка текстовых данных в pandas часто начинается с удаления пунктуации и служебных символов. Распространённая ловушка: передать регулярное выражение в Series.str.replace, не включив режим regex. Итог сбивает с толку — ничего не меняется, — хотя шаблон выглядит корректным.
Как воспроизвести проблему
В следующем фрагменте мы пытаемся убрать все небуквенно-цифровые символы из столбца desc, загруженного из 911.csv.
import pandas as pd
calls_df = pd.read_csv('911.csv')
calls_df['desc'].str.replace('[^a-zA-Z0-9]', '').head()Несмотря на символьный класс, который должен совпадать со всем, кроме букв и цифр, содержимое столбца остаётся прежним.
Что происходит
Series.str.replace может воспринимать первый аргумент либо как буквальную строку, либо как регулярное выражение. Если обработка регулярных выражений не включена, движок не трактует спецсимволы — квадратные скобки, каретки и диапазоны — как шаблон. На практике это означает, что замена не находит ожидаемых совпадений, и текст не меняется.
Решение
Включите режим regex явно. Этого достаточно, чтобы символьный класс заработал как задумано. Подробности — в документации pandas Series.str.replace.
calls_df['desc'].str.replace('[^a-zA-Z0-9]', '', regex=True).head()Ещё одна тонкость: этот шаблон также удаляет пробелы между словами. Если их нужно сохранить, добавьте пробел в разрешённый набор, включив его в символьный класс.
calls_df['desc'].str.replace('[^a-zA-Z0-9 ]', '', regex=True).head()Не-ASCII буквенные символы
Шаблон [^a-zA-Z0-9] исключает любые буквенные символы вне диапазона ASCII. Например, он превратит Düsseldorf в Dsseldorf. Если важно сохранить не-ASCII буквы, используйте \w вместо a-zA-Z.
calls_df['desc'].str.replace(r'[^\w]', '', regex=True).head()И если вы также хотите оставить пробелы, сохранив при этом не-ASCII буквы, разрешите пробел и в отрицательном классе.
calls_df['desc'].str.replace(r'[^\w ]', '', regex=True).head()Почему это важно
Нормализация текста — основа последующей аналитики, поиска и сопоставления. Тихая путаница между буквальным и регулярным режимами может незаметно сломать этап очистки и дать неоднородный вход для извлечения признаков или агрегации. Не менее важно контролировать, что именно вы сохраняете: удаление пробелов меняет границы токенов, а вычищение не-ASCII букв искажает имена и названия мест.
Выводы
При замене строк в pandas по шаблону включайте параметр regex=True. Заранее решите, должны ли пережить очистку пробелы, и подправьте символьный класс соответственно. Если в данных есть не-ASCII текст, предпочитайте \w, чтобы сохранить такие буквы. Эти небольшие, но осознанные решения делают препроцессинг предсказуемым, а результаты — надёжными.
Статья основана на вопросе с StackOverflow от david yen2 и ответе furas.