当用多列调用set_index时,datetime.date值将转换为pd.tslib.Timestamps



根据标题,pandas在执行set_index时强制将datetime.date类型转换为pd.tslib.Timestamp类型,但前提是索引中有多列。这使得处理和合并不同的帧成为一个问题,因为有些帧最终带有时间戳,而另一些帧则保留为datetime.dates。超级简单的例子:

df = pd.DataFrame({'date':[datetime.date(2021,3,3),datetime.date(2021,3,4)],'player':['a','b'],'score':[10,9]})
print(type(df['date'][0]))
<class 'datetime.date'>
df = df.set_index('date')
print(type(df.index.get_level_values('date')[0]))
<class 'datetime.date'>
df = df.reset_index()
print(type(df['date'][0]))
<class 'datetime.date'>
df = df.set_index(['date','player'])
print(type(df.index.get_level_values('date')[0]))
<class 'pandas.tslib.Timestamp'>
df = df.reset_index()
print(type(df['date'][0]))
<class 'pandas.tslib.Timestamp'>

我如何将它们保存在datetime.date?

[注意:pd.版本==0.19.2'由于遗留代码,如果相关的话]

我认为这是个bug。

您可以使用MultiIndex.set_levels,并通过DatetimeIndex.date:设置为dates

df = df.set_index(['date','player'])
df.index = df.index.set_levels(df.index.levels[0].date, level=0)
print(type(df.index.get_level_values('date')[0]))
<class 'datetime.date'>
df = df.reset_index()
print(type(df['date'][0]))
<class 'datetime.date'>

我找到了一个解决方法,但我确实希望能提供更好的答案,因为这是一种效率很低的方法,需要相当多的行数。

解决方法:

  1. 将多索引设置为正常
  2. 取消堆叠,直到只有您的日期列保留为索引
  3. 将值转换回datetime.dates,并通过列表设置索引,然后重新命名索引
  4. 将df堆叠回其原始布局
df = pd.DataFrame({'date':[datetime.date(2021,3,3),datetime.date(2021,3,4)],'player':['a','b'],'score':[10,9]})
df = df.set_index(['date','player'])
df = df.unstack()
df.index = [d.date() for d in df.index.to_pydatetime()]
df.index.names = ['date']
df = df.stack()
print(type(df.index.get_level_values('date')[0]))
<class 'datetime.date'>

最新更新