Нашли ошибку?
среднийpandas 3.0.6

Строки: .str и тип str

Очистить и разобрать текстовые столбцы — регистр, пробелы, поиск, разбиение, извлечение по шаблону.

Нужно знать:Выбор столбцовФильтрация строк

Содержание статьи

Коротко

  • Строковые методы вызываются через .str: s.str.lower(), s.str.contains("x"). Они работают с каждым значением и пропускают NaN.
  • В pandas 3 строки по умолчанию хранятся в типе str (раньше — object).
  • contains, replace, split, extract по умолчанию понимают регулярные выражения. Для поиска обычного текста — regex=False.
  • split(expand=True) раскладывает части по столбцам; extract(r"(...)") достаёт группы шаблона.
  • s.str[:4] — срез каждой строки, s.str.len() — длины.

Синтаксис

s.str.strip(), s.str.lower(), s.str.upper(), s.str.title()
s.str.contains(pat, case=True, regex=True, na=None)
s.str.startswith(prefix), s.str.endswith(suffix)
s.str.split(sep, n=-1, expand=False)
s.str.extract(r"(группа)", expand=True)
s.str.replace(pat, repl, regex=False)
s.str.len(), s.str[i:j], s.str.cat(sep=", ")

Параметры

ПараметрЧто делаетПо умолчанию
patподстрока или регулярное выражениеобязательный
regexв contains — True, в replace — False: считать ли pat регулярным выражениемTrue / False
caseв contains: учитывать регистрTrue
expandв split / extract: вернуть DataFrame со столбцамиFalse / True
nв split: максимум разбиений-1 (все)

Примеры

Данные для примеровиспользуются во всех примерах ниже
clients = pd.DataFrame({
    "name": ["  анна ПЕТРОВА", "Борис Иванов ", "вика сидорова", None],
    "email": ["anna@mail.ru", "boris@yandex.ru", "vika@mail.ru", "x@gmail.com"],
    "phone": ["+7 (912) 345-67-89", "8-912-111-22-33", "89125554433", "—"],
})
Пробелы и регистр
clients["name"].str.strip().str.title()
Вывод
0     Анна Петрова
1     Борис Иванов
2    Вика Сидорова
3              NaN
Name: name, dtype: str
Строки, содержащие текст
clients[clients["email"].str.contains("mail.ru", regex=False)]
Вывод
             name         email               phone
0    анна ПЕТРОВА  anna@mail.ru  +7 (912) 345-67-89
2   вика сидорова  vika@mail.ru         89125554433
Начинается / заканчивается на
clients["email"].str.endswith("@mail.ru")
Вывод
0     True
1    False
2     True
3    False
Name: email, dtype: bool
Разбить на столбцы
clients["name"].str.strip().str.split(" ", expand=True)   # в отдельные столбцы
Вывод
       0         1
0   анна   ПЕТРОВА
1  Борис    Иванов
2   вика  сидорова
3    NaN       NaN
Извлечь по шаблону
clients["email"].str.extract(r"@(\w+)\.")                 # группа регулярного выражения
Вывод
        0
0    mail
1  yandex
2    mail
3   gmail
Замена по шаблону
clients["phone"].str.replace(r"\D", "", regex=True)       # оставить только цифры
Вывод
0    79123456789
1    89121112233
2    89125554433
3
Name: phone, dtype: str
Длина и срез
print(clients["email"].str.len().tolist())
clients["email"].str[:4]                                   # первые 4 символа
Вывод
[12, 15, 12, 11]
0    anna
1    bori
2    vika
3    x@gm
Name: email, dtype: str
Склеить значения
clients["name"].str.strip().str.cat(sep=", ")              # склеить значения столбца
Вывод
'анна ПЕТРОВА, Борис Иванов, вика сидорова'

Подводные камни

Точка и другие символы в регулярном выражении

В contains точка означает «любой символ». Для поиска текста как есть передайте regex=False.

contains с точкой
clients["email"].str.contains(".ru").tolist()              # «.» в регулярном выражении — любой символ
Вывод
[True, True, True, False]

.str у нестроковых столбцов

.str для чиселошибка: AttributeError
pd.Series([1, 2]).str.len()                                # .str только для строк
Ошибка
AttributeError: Can only use .str accessor with string values, not integer

Сначала приведите к строкам: s.astype(str).str.len().

Пропуски в строковых методах

Методы, возвращающие строки, сохраняют NaN. А contains и startswith в типе str возвращают для пропуска False — строка с пропуском не попадёт в фильтр.

Пропуск в upper и contains
print(clients["name"].str.upper().tolist())                # пропуск остаётся пропуском
clients["name"].str.contains("ов").tolist()                # а у contains для пропуска — False
Вывод
['  АННА ПЕТРОВА', 'БОРИС ИВАНОВ ', 'ВИКА СИДОРОВА', nan]
[False, True, True, False]