По разным причинам я хочу обработать Pandas DataFrame, который имеет такую общую структуру:
import pandas
exampledf = pandas.DataFrame([
{'PersonId':'123','Interest':'Basketball','SubmittedDate':datetime.datetime.strptime('2018-04-18 13:00:08', '%Y-%m-%d %H:%M:%S'),'Question':'Cake or death?'},
{'PersonId':'123','Interest':'Baseball','SubmittedDate':datetime.datetime.strptime('1999-01-01 09:00:00', '%Y-%m-%d %H:%M:%S'),'Question':'Swallow speed?'},
{'PersonId':'456','Interest':'Swimming','SubmittedDate':datetime.datetime.strptime('2011-02-27 23:00:00', '%Y-%m-%d %H:%M:%S'),'Question':'Answer to life, universe, everything?'},
{'PersonId':'123','Interest':'Basketball','SubmittedDate':datetime.datetime.strptime('2018-04-18 13:00:00', '%Y-%m-%d %H:%M:%S'),'Question':'N/A'},
{'PersonId':'789','Interest':'Racquetball','SubmittedDate':datetime.datetime.strptime('2018-05-02 12:00:00', '%Y-%m-%d %H:%M:%S'),'Question':'Will there be food?'},
{'PersonId':'789','Interest':'Racquetball','SubmittedDate':datetime.datetime.strptime('2002-05-28 02:00:00', '%Y-%m-%d %H:%M:%S'),'Question':'Swag?'},
{'PersonId':'789','Interest':'Racquetball','SubmittedDate':datetime.datetime.strptime('2018-05-02 12:00:00', '%Y-%m-%d %H:%M:%S'),'Question':'Good, thanks.'}
])
exampledf.set_index(['PersonId','Interest'], inplace=True)
print(exampledf)
Следовательно, выглядит так:
Question SubmittedDate
PersonId Interest
123 Basketball Cake or death? 2018-04-18 13:00:08
Baseball Swallow speed? 1999-01-01 09:00:00
456 Swimming Answer to life, universe, everything? 2011-02-27 23:00:00
123 Basketball N/A 2018-04-18 13:00:00
789 Racquetball Will there be food? 2018-05-02 12:00:00
Racquetball Swag? 2002-05-28 02:00:00
Racquetball Good, thanks. 2018-05-02 12:00:00
Я хочу сохранить свой вывод вта же структура, что и у моего ввода, но за исключением любых строк, которые не имеют последней SubmittedDate, произвольно разрывая связи (первая найденная строка в порядке).
Я нашел много способов сделать это вообще (все виды дополнительного удаления и повторного добавления индексов) .Например:
- Я могу сделать
exampledf.reset_index()
перед выполнением .groupby()
, а затем просто .set_index()
снова после того, как я закончу, но это кажется неудобным
Но я изо всех сил пытаюсь сделать это элегантно.Например:
- Я могу
.groupby(level=[0,1])
, который добавляет избыточные уровни "PersonId" и "Interest", и это не вызывает проблемы для ".max ()", и который возвращаетсяк общему виду и ощущению просто отлично с .reset_index(level=[0,1], drop=True)
, но когда я пытаюсь втиснуть drop_duplicates()
в «PersonId», «Interest» и «SubmittedDate» где-то во всем этом, я не могу получить егоработать так, чтобы не требовалось больше группировки и сброса.
Например, это дает мне ошибку KeyError: 'PersonId'
:
lastsubmittedperlookuptiesbrokendf = exampledf.groupby(level=[0,1]).apply(lambda x: x[x['SubmittedDate'] == x['SubmittedDate'].max()]).reset_index(level=[0,1], drop=True, inplace=False).drop_duplicates(subset=['PersonId','Interest','SubmittedDate'])
Как это происходит:
lastsubmittedperlookuptiesbrokendf = exampledf.groupby(level=[0,1]).apply(lambda x: x[x['SubmittedDate'] == x['SubmittedDate'].max()]).drop_duplicates(subset=['PersonId','Interest','SubmittedDate']).reset_index(level=[0,1], drop=True, inplace=False)
Какой самый Pythonic способ получить следующий вывод?
Question SubmittedDate
PersonId Interest
123 Baseball Swallow speed? 1999-01-01 09:00:00
Basketball Cake or death? 2018-04-18 13:00:08
456 Swimming Answer to life, universe, everything? 2011-02-27 23:00:00
789 Racquetball Will there be food? 2018-05-02 12:00:00
(Обратите внимание, что моя текущая неуклюжая реализация пересортировала интересы, но мне все равно, в каком порядке онисортировать.)