Текстовые столбцы: нормализация и разбор через .str
Содержание курса
В прошлом уроке мы разбирались с пропусками: обнаруживали их, удаляли или заполняли. Там же появился StringDtype — тип, специально заточенный под текстовые столбцы. В этом уроке переходим к следующему шагу: что делать с самим текстом, когда данные пришли грязными — с лишними пробелами, случайным регистром, склеенными подстроками.
Аксессор .str: механизм поэлементной работы со строками
Когда в таблице есть текстовый столбец, первый инстинкт — пройтись по нему циклом и применить нужную строковую функцию к каждой ячейке. Это работает, но требует явного кода и не даёт pandas возможности обрабатывать данные в своём стиле. pandas предлагает стандартный способ — аксессор .str.
Аксессор — это особый «мост» между Series и строковыми методами Python. Обращаясь к series.str, вы получаете объект, который применяет строковые операции ко всем элементам Series поэлементно, без явного цикла в вашем коде.
Механика простая: series.str.method(...) берёт каждый элемент Series, вызывает на нём метод и складывает результаты в новый Series той же длины и с тем же индексом.
import pandas as pd
s = pd.Series([' Alice ', 'BOB', 'carol'])
print(s.str.lower())
# 0 alice
# 1 bob
# 2 carol
# dtype: object
Это идиоматичный pandas-стиль: вместо for-цикла вы описываете операцию декларативно, и pandas выполняет её внутри себя. Для object-столбцов прирост скорости по сравнению с циклом не гарантирован — он зависит от конкретной операции и версии pandas. Ценность .str прежде всего в читаемости, единообразии и корректной обработке пропусков.
Какие столбцы поддерживают .str. Аксессор работает с Series, у которых dtype равен object или StringDtype. Большинство текстовых столбцов при загрузке через read_csv получают тип object — это стандартный случай. StringDtype (pd.StringDtype()) — более строгий nullable-вариант, который явно обозначает, что в столбце только строки или pd.NA.
Поведение при пропусках. Если элемент в Series равен NaN или pd.NA, аксессор не падает с ошибкой. Он просто пропускает такой элемент и возвращает на его месте тот же NaN/pd.NA.
s_with_na = pd.Series(['Alice', None, 'carol'])
print(s_with_na.str.lower())
# 0 alice
# 1 None
# 2 carol
# dtype: object
Пропуски не превращаются в строку 'none' или пустую строку — они остаются пропусками. Если дальше нужна булева маска, это поведение стоит контролировать отдельно — об этом позже.
Исходный Series не изменяется. Каждый вызов .str.method() возвращает новый Series. Чтобы сохранить результат, нужно явно присвоить его столбцу или переменной.
Аксессор .str — стандартный инструмент для массовой работы с текстом в pandas. Всё, что разбирается в этом уроке — нормализация, разбивка, фильтрация — работает именно через него.
