#python #pandas #dataframe
Вопрос:
Предположим, что у нас есть фрейм данных Pandas (df) в виде:
прозвище | событие | Дата |
---|---|---|
A | 0 | 2020-01-02 |
A | 1 | 2020-01-03 |
B | 0 | 2020-01-02 |
B | 0 | 2020-01-03 |
C | 1 | 2020-01-02 |
C | 1 | 2020-01-03 |
Есть ли быстрый и элегантный способ получить только те строки, в которых у прозвища никогда не было события 1? Нравится
прозвище | событие | Дата |
---|---|---|
B | 0 | 2020-01-02 |
B | 0 | 2020-01-03 |
Я придумал следующий код, чтобы решить эту проблему
df_group= df.groupby('nickname')['event'].max()
df_never = df_group[df_group == 0]
df_only_never = df[df['nickname'].isin(df_never .index)]
У меня такое чувство, что есть однострочный способ сделать это с Пандами, но я не уверен, как это сделать.
Ответ №1:
Вы можете использовать .groupby
.filter
:
x = df.groupby("nickname").filter(lambda x: x["event"].eq(0).all())
print(x)
С принтами:
nickname event Date
2 B 0 2020-01-02
3 B 0 2020-01-03
Ответ №2:
Ваши коды близки. Вместо того, чтобы использовать .max()
агрегат и уменьшать количество строк, вы можете использовать .transform()
'max'
, чтобы все значения группы были равны максимальному значению (либо 0, либо 1 для всей группы).
Затем, как и вы, проверьте эти значения на равенство, 0
чтобы получить логический индекс.
Наконец, используйте .loc
логический индекс, чтобы найти строки группы(групп) со всеми нулями, как показано ниже:
df_out = df.loc[df.groupby('nickname')['event'].transform('max') == 0]
Результат:
print(df_out)
nickname event Date
2 B 0 2020-01-02
3 B 0 2020-01-03
Комментарии:
1. @EduardoPacheco Добро пожаловать! Хорошо используйте
.transform()
функцию, которая дает вам одинаковое количество исходных строк. Следовательно, вы можете затем использовать результат вместе со столбцом для прямого сравнения и других операций, которые невозможны, когда вы получаете агрегированные результаты.agg()
с меньшим количеством строк. Счастливого программирования! 🙂