#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. Обновил свой ответ