使用 MultiIndex 时如何将此 Pandas 列类型保留为日期时间?

Eze*_*ick 3 python datetime timestamp multi-index pandas

这太奇怪了,我真的想知道我是否只是误解了事情。

我有一些从日期时间值构建多重索引的代码,但生成多重索引后,类型已更改为时间戳。我希望它保留日期时间。我为什么要关心?好吧,代码的另一部分以与相同日期时间略有不同的方式生成多索引,但在这种情况下,它保留 datettime 类型 - 所以我不能在两个 DataFrame 之间使用更新,因为列不被视为相等(是的,我通过直接比较值进行检查)。

下面是最小的代码示例:

import datetime
import pandas as pd
import numpy as np

iterables = [['bar', 'baz', 'foo', 'qux'], [datetime.date(2014, 10, 3)]]
columns = pd.MultiIndex.from_product(iterables)
df = pd.DataFrame(np.random.randn(4, 4),columns = columns)
Run Code Online (Sandbox Code Playgroud)

这给出:

>>> df.columns[0]
('bar', Timestamp('2014-10-03 00:00:00'))
Run Code Online (Sandbox Code Playgroud)

请注意,日期的类型现在是时间戳,而不是日期时间。在我的代码的另一部分中,它保持 datettime (这是正确的事件链,是吗?),所以现在它们都引用相同的日期,但测试不相等,所以我无法应用 DataFrame.update 从一个推送数据到另一个。不幸的是,这两条路径都有强有力的数据驱动原因,说明为什么它们应该按照现在的方式完成。

有什么解决方法或解决方案吗?或者我是否错过了一些明显的东西,整个前提很愚蠢(我不会以某种方式在这里将其视为一种可能性 - 我很惊讶日期时间测试不等于时间戳)?有没有一种简单的方法可以进入并更改多重索引的第二级类型以将其更改回日期时间?

编辑:差点忘了:pandas 版本 0.15.2

unu*_*tbu 5

在构建 a 时MultiIndex值变为Categoricals

Categoricalsdatetimes 自动转换Timestamps为:

In [287]: pd.Categorical([datetime.date(2014, 10, 3)])[0]
Out[287]: Timestamp('2014-10-03 00:00:00')
Run Code Online (Sandbox Code Playgroud)

Categoricalan 却Index没有

In [288]: pd.Categorical(pd.Index([datetime.date(2014, 10, 3)]))[0]
Out[288]: datetime.date(2014, 10, 3)
Run Code Online (Sandbox Code Playgroud)

所以,

import datetime
import pandas as pd

iterables = [['bar', 'baz', 'foo', 'qux'], pd.Index([datetime.date(2014, 10, 3)])]
columns = pd.MultiIndex.from_product(iterables)
df = pd.DataFrame(np.random.randn(4, 4),columns=columns)
print(df.columns[0])
Run Code Online (Sandbox Code Playgroud)

产量

('bar', datetime.date(2014, 10, 3))
Run Code Online (Sandbox Code Playgroud)

请注意,我知道更改 DataFrame 的 MultiIndex 的最简单方法是重新分配新的 MultiIndex。因此,如果df已经有带有时间戳的 MultiIndex,要将 MultiIndex 转换为日期时间,请使用:

iterables = [['bar', 'baz', 'foo', 'qux'], pd.Index([datetime.date(2014, 10, 3)])]
columns = pd.MultiIndex.from_product(iterables)
df.columns = columns
Run Code Online (Sandbox Code Playgroud)