#python #pandas #dense-rank
Вопрос:
Я хочу иметь эквивалент ранга SQL в модуле python pandas. Я хочу отфильтровать все даты, которые имеют ранг = 1
У меня есть следующий фрейм данных:
id date
12 2021-06-01
12 2021-06-15
12 2021-06-21
34 2021-06-05
87 2021-06-19
53 2021-06-05
и мне нужно применить ранг следующим образом:
id date rank
12 2021-06-01 1
12 2021-06-15 2
12 2021-06-21 3
34 2021-06-05 1
87 2021-06-19 1
53 2021-06-05 1
SQL для этого был бы
select id, date, rank() over (partition by id order by date asc) as rank
from table;
Ответ №1:
Использование IIUC GroupBy.rank
:
df['date'] = pd.to_datetime(df['date'])
df['rank'] = df.groupby('id')['date'].rank(method='dense').astype(int)
print (df)
id date rank
0 12 2021-06-01 1
1 12 2021-06-15 2
2 12 2021-06-21 3
3 34 2021-06-05 1
4 87 2021-06-19 1
5 53 2021-06-05 1
Если даты и время отсортированы по группам, возможно GroupBy.cumcount
:
df = df.sort_values(['id','date'])
df['rank'] = df.groupby('id')['date'].cumcount().add(1)
Комментарии:
1. Это ошибка: «pandas.core.base. Ошибка данных: Нет числовых типов для агрегирования»
2. @Prudhavi — Можете ли вы добавить
df['date'] = pd.to_datetime(df['date'])
перед моим решением?3. Сработало как заклинание. Спасибо. А также я не знал, что мы можем изменить весь столбец на дату, используя pd.to_dateframe. Полезный совет.