Замена значений строк с одинаковым идентификатором на максимальную дату

#python #pandas

#python #pandas

Вопрос:

Ниже приведен сценарий для упрощенной версии рассматриваемого df:

 import pandas as pd
    
df = pd.DataFrame({ 
                   'id': ['1', '1','2','2','3','3','4','4','5','6','7'],
                   'product1_expiry_date' : ['-','-','2020-11-28','2020-11-13','-',
                                             '2020-11-13','2020-12-13','-','2020-11-16','-',
                                             '2020-11-28'],
                   'product2_expiry_date' : ['2020-11-16','2020-11-19','-',
                                             '-','2020-11-23','2020-11-13',
                                             '2020-12-13','-','2020-12-01','2020-12-01',
                                             '2020-12-14']
                 })
 df

id  product1_expiry_date    product2_expiry_date
1            -                   2020-11-16
1            -                   2020-11-19
2        2020-11-28                  -
2        2020-11-13                  -
3            -                   2020-11-23
3        2020-11-13              2020-11-13
4        2020-12-13              2020-12-13
4            -                         -
5        2020-11-16              2020-12-01
6            -                   2020-12-01
7        2020-11-28              2020-12-14
  

Я хотел бы не иметь повторяющихся идентификаторов, для каждого идентификатора отбрасывая более ранние даты и значения ‘-‘, где это применимо. Поскольку меня интересуют только более поздние даты.

ПРЕДПОЛАГАЕМЫЙ DF:

    id   product1_expiry_date    product2_expiry_date
    1            -                  2020-11-19
    2        2020-11-28                 -
    3        2020-11-13             2020-11-23
    4        2020-11-13             2020-11-13
    5        2020-12-13             2020-12-13
    6        2020-11-16             2020-12-01
    7        2020-11-28             2020-12-14
  

Любая помощь будет принята с благодарностью.

Ответ №1:

Преобразовать Id в индекс, затем преобразовать все столбцы в datetimes и использовать max для каждого индекса:

 f = lambda x: pd.to_datetime(x, errors='coerce')
df1 = df.set_index('id').apply(f).max(level=0)
print (df1)
   product1_expiry_date product2_expiry_date
id                                          
1                   NaT           2020-11-19
2            2020-11-28                  NaT
3            2020-11-13           2020-11-23
4            2020-12-13           2020-12-13
5            2020-11-16           2020-12-01
6                   NaT           2020-12-01
7            2020-11-28           2020-12-14
  

Если хотите заменить NaT на - возможно, но получите смешанные даты и времени со строками, поэтому следующая обработка должна быть проблемой:

 f = lambda x: pd.to_datetime(x, errors='coerce')
df1 = df.set_index('id').apply(f).max(level=0).fillna('-')
print (df1)
   product1_expiry_date product2_expiry_date
id                                          
1                     -  2020-11-19 00:00:00
2   2020-11-28 00:00:00                    -
3   2020-11-13 00:00:00  2020-11-23 00:00:00
4   2020-12-13 00:00:00  2020-12-13 00:00:00
5   2020-11-16 00:00:00  2020-12-01 00:00:00
6                     -  2020-12-01 00:00:00
7   2020-11-28 00:00:00  2020-12-14 00:00:00
  

Последний, если необходимо id , столбец:

 df1 = df1.reset_index()