2026, Jan 12 09:02
Как выбрать столбцы pandas DataFrame по подстрокам и regex
Показываем, как отбирать столбцы pandas DataFrame по подстрокам: строим единый regex для filter, альтернативно формируем список через in и .loc. Простой метод.
Когда нужно выбрать столбцы pandas DataFrame не по точным именам, а по набору подстрок, простое пересечение не спасёт. Такая ситуация часто встречается в аналитических пайплайнах: у вас есть список вроде ["date", "cat", "rabbit"], и вы хотите получить все столбцы, в названии которых встречаются эти токены, например cats_fostered, cats_adopted, rabbits_fostered и т. д.
Постановка задачи
Нужно отфильтровать столбцы по подстрокам из списка. Простое пересечение с именами столбцов не подходит — сохраняются только точные совпадения, а передача списка в фильтрацию по регулярному выражению вызывает ошибку.
import pandas as pd
raw_map = {
"date": ["2023-01-22","2023-11-16","2024-06-30","2024-08-16","2025-01-22"],
"cats_fostered": [1,2,3,4,5],
"cats_adopted": [1,2,3,4,5],
"dogs_fostered": [1,2,3,4,5],
"dogs_adopted": [1,2,3,4,5],
"rabbits_fostered": [1,2,3,4,5],
"rabbits_adopted": [1,2,3,4,5]
}
pet_df = pd.DataFrame(raw_map)
lookup_terms = ["date", "cat", "rabbit"]
# Не работает: пересечение требует точного совпадения имён столбцов
pet_df[pet_df.columns.intersection(lookup_terms)]
# Не работает: filter(regex=...) ожидает строковый шаблон, а не список
pet_df.filter(regex=lookup_terms)
Что происходит на самом деле
Корневая проблема — несоответствие между точным совпадением и поиском по подстроке. В DataFrame есть столбцы вроде cats_fostered и rabbits_adopted, а в вашем списке — cat и rabbit. Метод columns.intersection(...) сохраняет только те имена, которые в точности равны элементам списка, поэтому остаётся лишь date. При этом DataFrame.filter(regex=...) ожидает одну строку с регулярным выражением, а не список строк, и прямой проход списка приводит к ошибке.
Решение
Соберите единый шаблон регулярного выражения из подстрок и передайте его в filter. Удобно всегда оставлять date, а список сосредоточить на ключах животных. Так вы получите любые столбцы, где в названии встречается cat или rabbit, плюс столбец date.
# Сфокусируйте список только на животных и явно добавьте "date" в шаблон
animal_keys = ["cat", "rabbit"]
regex_rule = "date|" + "|".join(animal_keys)
pet_df.filter(regex=regex_rule)
Если нужен только один вид животного, подход остаётся тем же — просто измените список.
animal_keys = ["cat"]
regex_rule = "date|" + "|".join(animal_keys)
pet_df.filter(regex=regex_rule)
Есть и безрегулярный, строковый вариант, отражающий ту же идею: собрать список нужных столбцов через включение, а затем выбрать их из фрейма. Проверку вхождения можно делать в любой части имени столбца.
animal_keys = ["cat", "rabbit"]
chosen_cols = [c for c in pet_df.columns if c == "date" or any(mark in c for mark in animal_keys)]
pet_df.loc[:, chosen_cols]
Почему это важно
В обработке данных соглашения об именовании столбцов часто несут смысл через префиксы и вставки. Опираться на точные совпадения ненадёжно: это приводит к пустым выборкам или ошибкам. Единый шаблон регулярного выражения или простые строковые проверки делают намерение явным, хорошо масштабируются по мере изменений схемы и предотвращают неожиданные сбои, когда в именах есть суффиксы вроде _fostered или _adopted.
Итоги
Если вы фильтруете столбцы по списку токенов, рассматривайте это как поиск по подстрокам. Соберите одну строку для регулярного выражения через "|".join(...) и передайте её в DataFrame.filter(regex=...), при желании жёстко добавив стабильные столбцы вроде date. Если regex не по душе, сформируйте список столбцов с помощью включения и проверок in или startswith и выбирайте через .loc. Так логика отбора остаётся лаконичной, предсказуемой и легко адаптируемой по мере появления новых однотипно названных столбцов.