在熊猫`DataFrame`中将`TimeStamp`列截断为小时精度
Posted
技术标签:
【中文标题】在熊猫`DataFrame`中将`TimeStamp`列截断为小时精度【英文标题】:Truncate `TimeStamp` column to hour precision in pandas `DataFrame` 【发布时间】:2015-04-30 15:40:52 【问题描述】:我有一个名为df
的pandas.DataFrame
,它有一个自动生成的索引,其中有一列dt
:
df['dt'].dtype, df['dt'][0]
# (dtype('<M8[ns]'), Timestamp('2014-10-01 10:02:45'))
我想做的是创建一个截断到小时精度的新列。我目前正在使用:
df['dt2'] = df['dt'].apply(lambda L: datetime(L.year, L.month, L.day, L.hour))
这行得通,所以没关系。但是,我有一种使用pandas.tseries.offsets
或创建DatetimeIndex
或类似方法的好方法。
那么如果可能的话,有没有pandas
的魔法可以做到这一点?
【问题讨论】:
所以你想要相同的值但没有正确的秒数 @EdChum 没有分钟或秒...我只对小时精度感兴趣 【参考方案1】:在 pandas 0.18.0 及更高版本中,有 datetime floor
、ceil
和 round
方法将时间戳舍入到给定的固定精度/频率。要向下舍入到小时精度,您可以使用:
>>> df['dt2'] = df['dt'].dt.floor('h')
>>> df
dt dt2
0 2014-10-01 10:02:45 2014-10-01 10:00:00
1 2014-10-01 13:08:17 2014-10-01 13:00:00
2 2014-10-01 17:39:24 2014-10-01 17:00:00
这是截断时间戳的另一种方法。与floor
不同,它支持截断到年或月等精度。
您可以临时调整底层 NumPy datetime64
数据类型的精度单位,将其从 [ns]
更改为 [h]
:
df['dt'].values.astype('<M8[h]')
这会将所有内容截断为小时精度。例如:
>>> df
dt
0 2014-10-01 10:02:45
1 2014-10-01 13:08:17
2 2014-10-01 17:39:24
>>> df['dt2'] = df['dt'].values.astype('<M8[h]')
>>> df
dt dt2
0 2014-10-01 10:02:45 2014-10-01 10:00:00
1 2014-10-01 13:08:17 2014-10-01 13:00:00
2 2014-10-01 17:39:24 2014-10-01 17:00:00
>>> df.dtypes
dt datetime64[ns]
dt2 datetime64[ns]
同样的方法应该适用于任何其他单位:月'M'
,分钟'm'
,等等:
'<M8[Y]'
保持最新月份:'<M8[M]'
保持最新状态:'<M8[D]'
保持最新状态:'<M8[m]'
保持第二:'<M8[s]'
【讨论】:
很好的答案。 Waaay 比datetime.replace
快,这是 SO 上提到的最常见的解决方案。
我的 dt 系列有一个我想去掉的毫秒项 (+00:00)。您答案的第一部分似乎是四舍五入(将术语归零)但没有截断。您对 astype 的回答的第二部分起到了作用。谢谢!
对于分钟频率所有三个:'m'、'M' 和 'df.head()
中,所以我认为在应用 df['hour'].dt.floor('h')
后出现了问题。但并没有错,检查df['hour'].loc[0]
显示正确的小时截断。【参考方案2】:
我过去用来实现此目标的方法如下(与您已经在做的非常相似,但我想我还是会把它扔掉):
df['dt2'] = df['dt'].apply(lambda x: x.replace(minute=0, second=0))
【讨论】:
【参考方案3】:或者:
df.dt.index.to_period("h") # for the period
df.dt.index.to_period("h").to_timestamp() # for the timestamp truncated
将是实现这一目标的最不模棱两可(更pythonic?)的方式。
使用floor
/round
/ceil
进行更粗的一轮(月、年...),您会收到一条错误消息
ValueError: <YearEnd: month=12> is a non-fixed frequency
在此处查看讨论:https://github.com/pandas-dev/pandas/issues/15303
【讨论】:
以上是关于在熊猫`DataFrame`中将`TimeStamp`列截断为小时精度的主要内容,如果未能解决你的问题,请参考以下文章