Pandas创建MultiIndex时如何避免datetime.date对象被转为Timestamp
在Pandas MultiIndex中保留datetime.date类型不被转换为Timestamp的方法
出现该问题的核心原因是Pandas默认的类型推断逻辑会自动将datetime.date类的序列转换为datetime64[ns]类型,对应元素为Timestamp对象,因此后续用原生date对象索引时会触发KeyError。
解决方案1:创建索引时强制指定object类型
通过MultiIndex.from_arrays方法拆分层级创建,将日期层级强制指定为object类型,跳过Pandas的自动类型推断:
import pandas as pd import datetime travel = [('car', datetime.date(2021, 10, 1)), ('car', datetime.date(2021, 10, 2)), ('car', datetime.date(2021, 10, 3)), ('bus', datetime.date(2021, 10, 1))] # 拆分两个层级的元素 level0 = [item[0] for item in travel] level1 = [item[1] for item in travel] # 创建时指定日期层级为object类型,不会被自动转换为Timestamp ind = pd.MultiIndex.from_arrays([level0, pd.Series(level1, dtype="object")]) # 测试创建DataFrame df = pd.DataFrame(index=ind, columns=["distance"]) # 直接用datetime.date对象索引不会报错 print(df.loc[("car", datetime.date(2021, 10, 1))])
解决方案2:修改已有索引的层级类型
如果已经生成了转换为Timestamp的MultiIndex,可以通过set_levels修改,注意set_levels要求传入的层级值必须去重,这也是你之前尝试时报错的原因:
# 将原Timestamp类型的层级值批量转换为date对象,自动去重 new_level1 = df.index.levels[1].map(lambda ts: ts.date()) # 替换原有层级 df.index = df.index.set_levels([df.index.levels[0], new_level1]) # 测试索引 print(df.loc[("car", datetime.date(2021, 10, 1))])
替代方案
如果不需要强制保留date类型,也可以在索引时将date对象转换为Timestamp,同样可以避免KeyError:
df.loc[("car", pd.Timestamp(datetime.date(2021, 10, 1)))]
内容的提问来源于stack exchange,提问作者pabloagent
相关产品推荐
相关产品推荐

