I have the following dataframe:
import pandas as pd
data = pd.DataFrame({'car_id':[1,1,1,2,2,3],'brand':['a','a','a','a','a','b'],'date':
['01/2021','02/2022','03/2022','04/2022','05/2022','06/2022']})
data['date'] = pd.to_datetime(data['date'],format='%m/%Y')
Looks like:
'| | car_id | brand | date |
|---:|---------:|:--------|:--------------------|
| 0 | 1 | a | 2021-01-01 00:00:00 |
| 1 | 1 | a | 2022-02-01 00:00:00 |
| 2 | 1 | a | 2022-03-01 00:00:00 |
| 3 | 2 | a | 2022-04-01 00:00:00 |
| 4 | 2 | a | 2022-05-01 00:00:00 |
| 5 | 3 | b | 2022-06-01 00:00:00 |'
I need to pick for every car_id the next available date for the same brand, taking as reference it's own car_id max(date).
car_id 1 has a max(date) of 2022-03-01, so I would need a new column after grouping where it has the date 2022-04-01, because it's the next available date (or closest if you wish) from the it's own max_date for the brand 'a' (although it belongs to a car_id 2, it's the same brand!).
car_id 2 has a max(date) of 2022-05-01, which is the max(date) also for the brand (there is no next date available), there is another max(date) in the dataset but it's from another brand! so it should be NaT.
car_id 3 has also the max_date for it's own brand, so it's same as the previous case.
The desired output should look like:
'| | car_id | brand | date |
|---:|---------:|:--------|:--------------------|
| 0 | 1 | a | 2022-04-01 00:00:00 |
| 3 | 2 | b | NaT |
| 5 | 3 | b | NaT |'
I have been playing around with a simple group by max and trying to shift, but can't get it done:
data.groupby(['car_id','brand']).apply(lambda x: x['date'].max())
I can provide more context and larger examples if needed, but the pseudo code would be: for every model_id, pick its max(date) and look for the closest date in the same brand, if if max(model_id.date) == max(brand.date) then it's NaT.
-- EDIT --
Does not seem to work if you change the order on how the dataframe is created, notw for row with index 3 (car_id 2 and brand 'a') the month is now the 10th:
data = pd.DataFrame({'car_id':[1,1,1,2,2,3],'brand':
['a','a','a','a','a','b'],'date':
['01/2021','02/2022','03/2022','10/2022','05/2022','06/2022']})
Results in
'| | car_id | brand | date |
|---:|---------:|:--------|:--------|
| 0 | 1 | a | 01/2021 |
| 1 | 1 | a | 02/2022 |
| 2 | 1 | a | 03/2022 |
| 3 | 2 | a | 10/2022 |
| 4 | 2 | a | 05/2022 |
| 5 | 3 | b | 06/2022 |'
Results in
car_id brand
1 a 05/2022
2 a 10/2022
3 b NaN
Name: date, dtype: object
Expected to car_id 1 have 10/2022 as it's the max date for the brand 'a', expected car_id to have NaN because has the max_date for the brand NaN:
car_id brand
1 a 5/2022
2 a NaN
3 b NaN
Name: date, dtype: object