PANDAS: способ объединения строк, сгруппированных по полю

#pandas #pandas-groupby

#pandas #pandas-groupby

Вопрос:

У меня есть фрейм данных, который выглядит как:

 test1 = pd.DataFrame( {
    "ROUTE" : ["MIA-ORD", "MIA-AUA", "ORD-MIA", "MIA-HOU", "MIA-JFK", "JFK-MIA", "JFK-YYZ"],
    "TICKET" : ["123", "345", "123", "678", "456", "345", "456"],
    "COUPON" : [1,4,2,1,1,3,2],
    "PAX" : ["Jessica", "Alex", "Jessica", "Jamanica", "Ernest","Alex", "Ernest"],
    "PAID": [100.00,200.00,100.00,100.00,200.00,200.00,200.00]})
  

это дает мне

      ROUTE TICKET  COUPON       PAX   PAID
0  MIA-ORD    123       1   Jessica  100.0
1  MIA-AUA    345       4      Alex  200.0
2  ORD-MIA    123       2   Jessica  100.0
3  MIA-HOU    678       1  Jamanica  100.0
4  MIA-JFK    456       1    Ernest  200.0
5  JFK-MIA    345       3      Alex  200.0
6  JFK-YYZ    456       2    Ernest  200.0
  

что я пытаюсь сделать, так это объединить данные маршрута и купона, чтобы

      ROUTE          TICKET     COUPON       PAX     PAID
0  MIA-ORD-ORD-MIA    123       1-2       Jessica   100.0
1  JFK-MIA-MIA-AUA    345       3-4         Alex    200.0
2  MIA-HOU            678       1         Jamanica  100.0
3  MIA-JFK-JFK-YYZ    456       1-2        Ernest   200.0
  

До сих пор мне удавалось группировать по билетам, поскольку это очевидный общий идентификатор, и отсортированным купонам, поскольку порядок рейсов для ‘ALEX’ инвертирован.

 rs1 = test1.groupby(['TICKET']).apply(pd.DataFrame.sort_values,'COUPON')
  

Это приводит

             ROUTE TICKET  COUPON       PAX   PAID
TICKET                                           
123    0  MIA-ORD    123       1   Jessica  100.0
       2  ORD-MIA    123       2   Jessica  100.0
345    5  JFK-MIA    345       3      Alex  200.0
       1  MIA-AUA    345       4      Alex  200.0
456    4  MIA-JFK    456       1    Ernest  200.0
       6  JFK-YYZ    456       2    Ernest  200.0
678    3  MIA-HOU    678       1  Jamanica  100.0
  

но отсюда я не могу объединить МАРШРУТ и КУПОН.

Я пытался:

 st1=test1.groupby('TICKET').apply(lambda group: ','.join(group['ROUTE']))
  

Но это приводит только к объединению столбцов, отсортированных отдельно. не остальные данные.

 TICKET
123    MIA-ORD,ORD-MIA
345    MIA-AUA,JFK-MIA
456    MIA-JFK,JFK-YYZ
678            MIA-HOU
dtype: object
  

Есть идеи?

Ответ №1:

Мы можем использовать groupby в сочетании с agg , а затем применить '-'.join() :

 test1['COUPON']=test1['COUPON'].astype(str)

final = test1.groupby(['TICKET', 'PAX', 'PAID']).agg({'ROUTE':'-'.join,
                                                      'COUPON':'-'.join}).reset_index()
print(final)
  TICKET       PAX   PAID            ROUTE COUPON
0    123   Jessica  100.0  MIA-ORD-ORD-MIA    1-2
1    345      Alex  200.0  MIA-AUA-JFK-MIA    4-3
2    456    Ernest  200.0  MIA-JFK-JFK-YYZ    1-2
3    678  Jamanica  100.0          MIA-HOU      1
  

Комментарии:

1. Каким-либо образом сортировка может быть применена к КУПОНУ перед объединением? в результате у нас остался бы билет 345 с соответствующим порядком следования купонов и маршрутом

2. Я смог сделать это, выполнив сначала srting в groupby. затем снова применяем groupby с помощью agg.

3. rs1 = test1.groupby(['TICKET']).apply(pd.DataFrame.sort_values,'COUPON').reset_index(drop=True)