Как вывести в одном датафрейме результаты по студентам с баллами по математике и биологии ниже 80
Что проверяют
Умеете ли вы фильтровать DataFrame по нескольким условиям и понимаете ли, почему в pandas для этого нужны & и скобки, а не and. Следом часто уточняют: а если нужно «хотя бы по одному предмету ниже 80» и что делать, если оценки лежат в длинной таблице.
Как отвечать
Сначала уточните условие: «ниже 80 по математике и биологии» может значить оба предмета сразу или любой из них. Это разные фильтры, и сильный кандидат спрашивает, а не угадывает.
Для широкой таблицы, где у каждого студента есть колонки math и bio:
- булева маска:
df[(df['math'] < 80) & (df['bio'] < 80)]. Скобки обязательны, у&приоритет выше, чем у<; - «хотя бы один предмет»: тот же фильтр с
|вместо&; - через
.loc:df.loc[mask, ['name', 'math', 'bio']], если нужно сразу оставить только нужные колонки; - через
query:df.query('math < 80 and bio < 80'), внутри строкиandкак раз допустим; - много предметов:
df[['math', 'bio']].lt(80).all(axis=1), а для «любого».any(axis=1).
Если данные пришли из базы в длинном формате (student, subject, score), сначала разверните их: df.pivot_table(index='student', columns='subject', values='score'), и уже потом фильтруйте. Можно и без разворота: оставить строки нужных предметов, сгруппировать по студенту и проверить, что максимум меньше 80, а предметов ровно два. На больших объёмах такой фильтр дешевле сделать прямо в SQL и забрать в pandas готовый результат.
Где спотыкаются
Пишут df[(df['math'] < 80) and (df['bio'] < 80)] и получают ValueError: The truth value of a Series is ambiguous. Python пытается свести всю серию к одному bool, а pandas это запрещает.
Забывают скобки вокруг сравнений. Без них & выполняется первым, выражение превращается в цепочку сравнений, которую Python раскрывает через тот же and, и ошибка остаётся прежней.
Не думают о пропусках. Сравнение с NaN даёт False, поэтому студент без оценки по биологии молча выпадет из выборки. Скажите об этом вслух и спросите, как такие строки считать.