如何在pandas中使用DatetimeIndex列表对DataFrame进行索引筛选
你遇到的KeyError核心是2个诱因:
- 你传入的
DatetimeIndex和目标DataFrame的索引格式/精度/时区不匹配,即使肉眼看时间字符串一致,底层值也无法匹配 df.loc[]要求所有传入的索引值都必须存在于目标DataFrame的索引中,只要有一个值不存在就会直接抛出异常,不会返回匹配上的部分结果
第一步:先校验索引匹配度
先运行两行代码确认两边索引的属性是否一致:
# 查看目标DataFrame的索引类型和前2个值的完整格式 print(df.index.dtype, df.index[:2]) # 查看你要传入的DatetimeIndex的类型和前2个值的完整格式 print(indexes.dtype, indexes[:2])
常见的不一致场景有:
- 时区差异:比如df索引是
datetime64[ns, UTC](带时区),传入的索引是datetime64[ns](无时区) - 精度差异:比如df索引带毫秒/微秒后缀(如
2018-11-27 12:30:00.045),传入的索引只精确到秒
第二步:对应解决方法
场景1:时区不匹配
如果是df索引带时区,传入的索引无时区,将传入索引补充对应时区即可:
# 示例为UTC时区,替换为你df索引的实际时区即可 indexes = indexes.tz_localize('UTC')
如果是df索引无时区,传入的索引带时区,去掉传入索引的时区即可:
indexes = indexes.tz_localize(None)
场景2:精度不匹配
将两边索引统一到相同精度即可,比如统一到秒级:
# 把df的索引截断到秒级 df.index = df.index.floor('S') # 或者把传入的索引调整到和df索引相同的精度 indexes = indexes.floor('ms') # 示例为统一到毫秒,按需调整即可
场景3:仅保留匹配到的索引(忽略不存在的索引)
如果不需要所有传入的索引都匹配成功,只要返回存在的对应行,最稳妥的方法是用isin方法筛选,不会抛出KeyError:
result_df = df[df.index.isin(indexes)]
如果你一定要用loc方法,可以先过滤出存在的索引再传入:
exist_indexes = indexes.intersection(df.index) result_df = df.loc[exist_indexes]
内容的提问来源于stack exchange,提问作者Astrofolia
相关产品推荐
相关产品推荐

