Фрейм данных Python группируется по столбцам при создании новых столбцов

#python #pandas

Вопрос:

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

членид билет agegrp c1 c2 c3 d1 Дата
1 1 1 A A aa 2019-01-01
1 1 1 A A AB 2019-01-02
1 1 1 A A C пт 2019-01-01
1 2 1 A D C aa 2019-02-01
1 2 1 A D C пт 2019-02-01
2 3 4 C A C около 2019-03-01
2 3 4 C A C компакт-диск 2019-03-01
2 3 4 C A C бб 2019-03-01
2 3 4 C A C aa 2019-03-02
 df = pd.DataFrame( {
   'memberiD': [1,1,1,1,1,2,2,2,2],
   'ticketid': [1,1,1,2,2,3,3,3,3],
   'agegrp': [1,1,1,1,4,4,4,4],
   'c1': ['a','a','a','a','a','c','c','c','c'],
   'c2': ['a','a','a','d','d','a','a','a','a'],
   'c3': ['','','c','c','c','c','c','c','c'],
   'd1': ['aa','ab','ac','aa','ac','ca','cd','bb','aa']  
    } );

 

Я хочу сгруппироваться ticketid так, чтобы один идентификатор билета был представлен ровно в одной строке.
Для каждого идентификатора билета идентификатор участника и возраст должны быть точно такими же.
Для c1,c2,c3 в билете просто выберите наиболее часто встречающиеся отдельные 3, которые появляются-в случае ничьей подойдет любой из 3 лучших.
Для всех d1 в любом одном тикете возьмите наиболее часто встречающиеся отдельные 3, которые появляются, и вставьте их в столбцы d1,d2,d3-аналогично столбцам c1,c2,c3: если есть связь, подойдет любой из 3 лучших.
Для даты просто выберите самую раннюю дату, которая отображается для любого идентификатора билета.

Таким образом, результирующий кадр данных может быть:

членид билет agegrp c1 c2 c3 d1 d2 d3 Дата
1 1 1 A C aa AB пт 2019-01-01
1 2 1 A D C aa пт 2019-02-01
1 3 4 C A около компакт-диск бб 2019-03-01

Я попытался посмотреть индексацию в ticketid, но я не совсем уверен, как создать новые столбцы с помощью этой индексации…хотя я не уверен, что этот подход в целом верен.

Ответ №1:

Ты хочешь этого?

 from statistics import mode
from collections import Counter

final_df =df.groupby('ticketid', as_index=False).agg({'memberid': mode,'c1':mode, 'c2': mode, 'c3': mode,'date': min,'d1': list})
final_df['d1']  = final_df.d1.apply(lambda x: ','.join(list(Counter(x))[:3]) if len(x) >= 3 else ','.join(x))
final_df[['d1','d2','d3']] = final_df['d1'].str.split(',', expand=True)

 

Выход —

    ticketid  memberid c1 c2   c3        date  d1  d2    d3
0         1         1  A  A  NaN  2019-01-01  AA  AB    AC
1         2         1  A  D    C  2019-02-01  AA  AC  None
2         3         2  C  A    C  2019-03-01  CA  CD    BB
 

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

1. Ваше решение близко, но для расширения d1 столбца в d1,d2,d3 некоторые final_df['d1'] списки выглядят как [‘AA’, ‘AA’, Нет], и соединение выдает ошибку. Кроме того, иногда список выглядит как [«AA», «AA», «AA», «AB», «AB», «AC», «AC»], поэтому я бы хотел, чтобы наиболее распространенные 3 отдельных элемента: AA, AB и AC, но похоже, что ваша лямбда-функция возвращает только первые 3? Есть какие-нибудь предложения по этому поводу ?

2. Обновил свой ответ