Нашли ошибку?
Скачать чистый
урок 3 из 5≈ 20 минупражнения: 0 из 4

Фильтрация строк

Условие превращает столбец в маску из True и False, маска отбирает строки. Несколько условий соединяют & (и), | (или), ~ (не) — обязательно со скобками.

Python запустится при первом выполнении

Самый частый вопрос к таблице начинается со слов «найди строки, где…»: где цена выше 2000, где город — Казань, где купили больше пяти штук. Это фильтрация — отбор строк по условию. Она делается в два шага.

Шаг первый: маска

Сравним столбец с числом. Как и арифметика, сравнение выполняется для каждого значения:

[ ]Цена больше 3000?
import pandas as pd

orders = pd.read_csv("data/shop_orders.csv")
orders["price"] > 3000
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
0        True
1       False
2       False
3       False
4       False
        ...
2443    False
2444    False
2445    False
2446    False
2447    False
Name: price, Length: 2448, dtype: bool

Получился Series из True и False с типом bool — по одному ответу на каждую строку. Такой Series называют маской: True — строка подходит, False — нет. Сравнивать можно всеми операторами Python: >, >=, <, <=, == (равно), != (не равно).

Шаг второй: маска в скобках

Если передать маску в квадратные скобки таблицы, останутся только строки, где в маске True:

[ ]Только строки дороже 3000
orders[orders["price"] > 3000].head()
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
order_id date customer_id city channel category product price quantity
0 10001 2025-01-01 C095 Москва маркетплейс Аксессуары Кофемолка ручная 3200 2
7 10005 2025-01-02 C033 Казань маркетплейс Аксессуары Кофемолка ручная 3200 2
218 10135 2025-01-28 C185 Санкт-Петербург приложение Аксессуары Кофемолка ручная 3200 1
348 10217 2025-02-16 C195 Москва сайт Аксессуары Кофемолка ручная 3200 2
661 10424 2025-04-03 C219 Екатеринбург приложение Аксессуары Кофемолка ручная 3200 2

Обратите внимание на индекс слева: 0, 7, 218… Строки сохранили свои метки — об этом шла речь в прошлом уроке.

Обычно оба шага пишут в одну строку, как выше. Но маску можно сохранить в переменную — так код читается легче, а маску можно использовать повторно:

[ ]Маска с именем
is_tea = orders["category"] == "Чай"
tea = orders[is_tea]
print(len(tea))
print(tea["price"].mean())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
682
381.1143695014663
[ ]Упражнение 1Дорогие покупки решено

Сохраните в expensive строки таблицы orders, где цена строго больше 2000, а в n_expensive — сколько таких строк.

expensive = ...
n_expensive = ...

Считаем по маске

Если нужны не сами строки, а их количество, таблицу можно не фильтровать. В вычислениях True считается единицей, False — нулём. Поэтому сумма маски — сколько строк подошло, а среднее — какая это доля:

[ ]Сколько строк с пятью штуками и больше и какая это доля
many = orders["quantity"] >= 5
print(many.sum())
print(many.mean())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
168
0.06862745098039216

168 строк — 6.9 % таблицы.

[ ]Упражнение 2Доля Москвы решено

Сохраните в is_moscow маску: True у строк, где город — Москва. Затем в n_moscow — число таких строк, а в share_moscow — их долю среди всех строк.

is_moscow = ...
n_moscow = ...
share_moscow = ...

Несколько условий

Условия соединяют операторами:

Оператор Значит Строка подходит, если
& и выполнены оба условия
| или выполнено хотя бы одно
~ не условие не выполнено

Каждое условие берут в круглые скобки:

[ ]Новосибирск и цена выше 3000
orders[(orders["city"] == "Новосибирск") & (orders["price"] > 3000)]
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
order_id date customer_id city channel category product price quantity
1143 10731 2025-06-11 C011 Новосибирск маркетплейс Аксессуары Кофемолка ручная 3200 1
1378 10893 2025-07-25 C121 Новосибирск приложение Аксессуары Кофемолка ручная 3200 2
[ ]Сайт или приложение — и всё остальное
site_or_app = (orders["channel"] == "сайт") | (orders["channel"] == "приложение")
print(site_or_app.sum())
print((~site_or_app).sum())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
1821
627

Привычные and, or, not здесь не работают. Они ждут одно значение True или False, а получают целый столбец таких значений:

[ ]and вместо &ошибка: ValueError
orders[(orders["channel"] == "сайт") and (orders["price"] > 3000)]
Ошибкасохранённый · нажмите «Выполнить», чтобы получить свой
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Скобки обязательны, потому что & и | выполняются раньше сравнений — как умножение раньше сложения. Без скобок Python сначала вычислит "сайт" & orders["price"], что бессмысленно:

[ ]Забыли скобкиошибка: TypeError
orders[orders["channel"] == "сайт" & orders["price"] > 3000]
Ошибкасохранённый · нажмите «Выполнить», чтобы получить свой
TypeError: Cannot perform 'rand_' with a dtyped [int64] array and scalar of type [bool]
[ ]Упражнение 3Крупные покупки в Казани решено

Сохраните в kazan_big строки, где город — Казань и количество не меньше 5.

kazan_big = ...

Вопрос

Что выведет print((~(orders["channel"] == "сайт")).sum() == (orders["channel"] != "сайт").sum())?

[ ]Упражнение 4Особые и обычные решено

Назовём строку особой, если цена товара не ниже 2000 или количество не меньше 8. Сохраните в special все особые строки, а в ordinary — все остальные.

special = ...
ordinary = ...

Метод all() у маски отвечает одним True или False: во всех ли строках условие выполнено. Им удобно проверять себя после фильтрации — например, что в таблице tea из примера выше действительно только чай:

[ ]Во всех ли строках так
print((tea["category"] == "Чай").all())
print((orders["price"] >= 150).all())
print((orders["quantity"] >= 2).all())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
True
True
False

Итоги

  • Сравнение столбца даёт маску — Series из True и False.
  • таблица[маска] оставляет строки, где True; метки строк сохраняются.
  • маска.sum() — сколько строк подходит, маска.mean() — какая доля.
  • & — и, | — или, ~ — не; каждое условие в скобках; and, or, not не работают.

Подробнее в справочнике

Нашли ошибку?