如何以最Pythonic方式筛选已设多层索引的Pandas DataFrame最新提交行
解决方案:简洁处理多层索引DataFrame的最新行保留问题
你的需求其实可以用非常简洁的Pandas操作实现,不需要复杂的groupby+apply组合,核心思路是先排序再去重,或者利用idxmax直接定位目标行,两种方法都能完美保持原有的多层索引结构:
方法一:排序后去重(最直观简洁)
这种方法先按提交日期降序排列,让每个(PersonId, Interest)组里最新的行排在最前面,然后直接按索引层级去重,保留每组的第一行——完全匹配你的需求,包括同日期重复行保留首行的要求:
# 按SubmittedDate降序排序,确保最新的行在每组最上方 sorted_df = exampledf.sort_values('SubmittedDate', ascending=False) # 按多层索引的两个层级去重,保留每组第一行 result_df = sorted_df.drop_duplicates(level=[0, 1]) # 查看结果(和你想要的输出一致) print(result_df)
输出结果:
Question SubmittedDate PersonId Interest 123 Basketball Cake or death? 2018-04-18 13:00:08 789 Racquetball Will there be food? 2018-05-02 12:00:00 456 Swimming Answer to life, universe, everything? 2011-02-27 23:00:00 123 Baseball Swallow speed? 1999-01-01 09:00:00
方法二:利用idxmax直接定位目标行
如果不想改变原始数据的排序,也可以用groupby结合idxmax获取每个组中最新日期的首行索引,再提取对应行:
# 获取每个(PersonId, Interest)组中SubmittedDate最大的行的索引 max_date_indices = exampledf.groupby(level=[0, 1])['SubmittedDate'].idxmax() # 根据索引提取行,自动保留同日期的首行 result_df = exampledf.loc[max_date_indices]
这个方法的优势是不会改变剩余行的相对顺序,同样能得到你需要的结果。
为什么你之前的代码报错?
你遇到的KeyError: 'PersonId'是因为PersonId和Interest是DataFrame的索引层级,不是普通列,在apply的子DataFrame里,你不能用x['PersonId']来访问它们,需要用x.index.get_level_values('PersonId')——但这种写法既繁琐又没必要,上面的两种方法显然更Pythonic。
内容的提问来源于stack exchange,提问作者k..
相关产品推荐
相关产品推荐

