Python Эквивалентен рангу SQL

#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. Полезный совет.