Как фильтровать DataFrame в pandas
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Базовый синтаксис
df[df['column'] > 100]df['column'] > 100 возвращает Series булевых значений. df[...] оставляет только строки, где True.
1. Простое условие
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'David'],
'age': [30, 25, 35, 28],
'city': ['Moscow', 'SPb', 'Moscow', 'Kazan']
})
# возраст больше 27
df[df['age'] > 27]
# город — Москва
df[df['city'] == 'Moscow']
# НЕ Москва
df[df['city'] != 'Moscow']2. Несколько условий (AND, OR)
Важно: используйте &, |, ~ (битовые операторы), не and, or, not.
И скобки обязательны вокруг каждого условия:
# AND
df[(df['age'] > 25) & (df['city'] == 'Moscow')]
# OR
df[(df['age'] < 25) | (df['city'] == 'Moscow')]
# NOT
df[~(df['city'] == 'Moscow')]Забыть скобки — частая ошибка:
# SyntaxError / неверный результат
df[df['age'] > 25 & df['city'] == 'Moscow']
# правильно
df[(df['age'] > 25) & (df['city'] == 'Moscow')]3. isin — значение в списке
# город в списке
df[df['city'].isin(['Moscow', 'SPb'])]
# НЕ в списке
df[~df['city'].isin(['Moscow', 'SPb'])]4. between — диапазон
df[df['age'].between(25, 30)] # inclusive обе границы
df[df['age'].between(25, 30, inclusive='neither')] # без границ
df[df['age'].between(25, 30, inclusive='left')] # включая левую5. Строковые методы (.str)
# имена, начинающиеся с A
df[df['name'].str.startswith('A')]
# имена, заканчивающиеся на e
df[df['name'].str.endswith('e')]
# содержит подстроку
df[df['name'].str.contains('li')]
# case-insensitive
df[df['name'].str.contains('ali', case=False)]
# по regex
df[df['name'].str.contains(r'^[AB]')] # начинается с A или B6. Null / NaN
# строки с NaN в age
df[df['age'].isna()]
# без NaN
df[df['age'].notna()]
# или
df[df['age'].notnull()]
# любая колонка содержит NaN
df[df.isna().any(axis=1)]
# все колонки без NaN
df[df.notna().all(axis=1)]7. query — SQL-подобный синтаксис
# удобно для сложных условий
df.query('age > 25 and city == "Moscow"')
# с переменной
min_age = 25
df.query('age > @min_age')
# несколько условий
df.query('age > 25 and city in ["Moscow", "SPb"]')Плюсы query: читаемее при длинных условиях.
8. По нескольким колонкам одновременно
# любая из колонок содержит слово
cols = ['name', 'city']
mask = df[cols].apply(lambda x: x.str.contains('Moscow')).any(axis=1)
df[mask]9. Top N / Bottom N
# 5 самых старших
df.nlargest(5, 'age')
# 5 самых младших
df.nsmallest(5, 'age')10. Через loc
Альтернативный синтаксис:
df.loc[df['age'] > 25]
# с одновременным выбором колонок
df.loc[df['age'] > 25, ['name', 'age']]11. Удалить строки по условию
Удалить — это то же самое, что оставить НЕ подходящие:
# удалить строки с age < 25
df = df[df['age'] >= 25]
# или через drop (по индексам)
df = df.drop(df[df['age'] < 25].index)12. Отфильтровать по индексу
# первые 10 строк (не по условию)
df.head(10)
# по списку индексов
df.loc[[0, 2, 4]]
# срез по индексу
df.loc[5:15]13. Фильтр + новая колонка
# флаг по условию (не фильтр, а аугментация)
df['is_moscow'] = df['city'] == 'Moscow'
# numpy.where
import numpy as np
df['status'] = np.where(df['age'] >= 30, 'senior', 'junior')14. Performance для больших DataFrame
# избегать .loc с boolean для очень больших данных
df[mask] # быстрее
df.loc[mask] # медленнее
df.query('cond') # чуть медленнее boolean, но читаемееДля огромных данных рассмотрите:
- категориальные dtypes (меньше памяти)
- numpy.where вместо apply
- vectorized операции
Частые ошибки
Ошибка 1. Использовать and вместо &
# TypeError или неверный результат
df[df['a'] > 0 and df['b'] < 10]
# правильно
df[(df['a'] > 0) & (df['b'] < 10)]Ошибка 2. Забыть скобки
# приоритет & выше, чем ==
df[df['age'] > 25 & df['city'] == 'Moscow'] # сломано
# правильно
df[(df['age'] > 25) & (df['city'] == 'Moscow')]Ошибка 3. Сравнение с NaN
# всегда False
df[df['age'] == np.nan]
# правильно
df[df['age'].isna()]Ошибка 4. SettingWithCopyWarning
filtered = df[df['age'] > 25]
filtered['new_col'] = 1 # warning!
# правильно
filtered = df[df['age'] > 25].copy()
filtered['new_col'] = 1Ошибка 5. isin с одиночным значением
# технически работает, но странно
df[df['city'].isin(['Moscow'])]
# короче
df[df['city'] == 'Moscow']Связанные темы
- Pandas шпаргалка для аналитика
- Как сортировать DataFrame в pandas
- groupby в pandas — шпаргалка
- isnull / dropna / fillna pandas
FAQ
df[...] или df.loc[...]?
Для простого boolean-фильтра — df[mask]. Для одновременного выбора строк и колонок — df.loc[mask, cols].
query или обычный синтаксис?
query читаемее при длинных условиях. Обычный быстрее и явнее. Вкусовщина.
Как отфильтровать по дате?
df[df['date'] > '2026-01-01']
df[pd.to_datetime(df['date']).dt.year == 2026]SettingWithCopyWarning — что делать?
.copy() после фильтрации, если собираетесь изменять.
Тренируйте Python и pandas — откройте тренажёр с 1500+ вопросами для собесов.