重置Pandas时间戳的时间部分

23

我该如何重置pandas时间戳的时间部分?

我想要重置pandas.Timestamp值中的时间部分。
我猜可以通过以下步骤实现。

  • 第一步)将Timestamp转换为datetime类型
  • 第二步)将datetime转换为秒数
  • 第三步)截取秒数中的时间部分
  • 第四步)将秒数转换回Timestamp

即使我的猜测是正确的,这也太费时间了。 有没有更简单的方法来达到这个目标呢?

In [371]: ts = pd.Timestamp('2014/11/12 13:35')

In [372]: ts

Out[372]: Timestamp('2014-11-12 13:35:00')

In [373]: ts.hour = 0 # <-- 这就是我想做的。


如果你正在处理一个“DatetimeIndex”,你可以使用normalize方法。然而,这个方法在单独的时间戳上不可用(解决方法是:pd.DatetimeIndex([ts]).normalize()[0])。 - joris
你想重置“整个”时间部分(仅保留日期),还是只想重置小时? - joris
6个回答

43

我认为你正在寻找replace方法(请参见文档):

In [18]: ts
Out[18]: Timestamp('2014-11-12 13:35:00')

In [19]: ts.replace(hour=0)
Out[19]: Timestamp('2014-11-12 00:35:00')

这是从datetime.datetime继承的一个方法。

如果你想要重置完整的时间部分,你可以在replace中指定所有部分:

In [20]: ts.replace(hour=0, minute=0, second=0)
Out[20]: Timestamp('2014-11-12 00:00:00')

还有一个 DatetimeIndex.normalize 方法,但是这个方法不能用于单个的时间戳(我已经为此开了一个 issue:https://github.com/pydata/pandas/issues/8794):

In [21]: pd.DatetimeIndex([ts]).normalize()[0]
Out[21]: Timestamp('2014-11-12 00:00:00')

这里最有价值的是,pandas时间戳继承自datetime!如果我早知道这一点,我就不会那么害怕了。:)谢谢! - KateYoak
replace方法似乎不能在列上使用,是吗?AttributeError: 'DatetimeProperties' object has no attribute 'replace' - Dr_Zaszuś
1
实际上,这不适用于列/索引。在这种情况下,如果您想使用“replace”,则需要使用类似于df["col"].apply(lambda ts: ts.replace(..))的东西(但请注意,“normalize”可用于列)。 - joris

2
请注意,replace方法不会改变时间戳,因此如果您想保留修改后的时间戳,您需要进行赋值操作:
In [2]: ts = pd.Timestamp('2014/11/12 13:35')
In [3]: ts.replace(hour=0)
Out[3]: Timestamp('2014-11-12 00:35:00')
In [4]: ts
Out[4]: Timestamp('2014-11-12 13:35:00')

注意:上面的代码没有修改ts。
In [5]: ts = ts.replace(hour=0)
In [6]: ts
Out[6]: Timestamp('2014-11-12 00:35:00')

1

1
还有Timestamp.floor这个函数:
>>> ts = pd.Timestamp('2014/11/12 13:35')
>>> ts.floor('D')
Timestamp('2014-11-12 00:00:00')
>>> ts.round('D')
Timestamp('2014-11-13 00:00:00')

但是,在我的机器上,Timestamp.normalizefloor快近30倍,而Timestamp.replace甚至比normalize还要快。
>>> %timeit ts.replace(hour=0, minute=0, second=0)
1.23 µs ± 17.2 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
>>> %timeit ts.normalize()
2.18 µs ± 137 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
>>> %timeit ts.floor('D')
62.7 µs ± 631 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

0
pd.Timestamp('2014-11-12 13:35') - pd.offsets.Micro(0, normalize=True) == Timestamp('2014-11-12 00:00:00')

0

我建议使用:

pd.Timestamp('2014-11-12 13:35')-pd.Timedelta(f"{pd.Timestamp('2014-11-12 13:35').hour} hours")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接