【发布时间】:2018-03-06 13:33:18
【问题描述】:
我想在 pandas python 中截断/舍入到小时的本地化日期时间列。例如,如果我有 2017-10-15 15:03:25+02:00 我想获得 2017-10-15 15:00:00+02:00。请注意,我想保留时区信息。 我尝试的第一件事是:
DF['dtColumn'].dt.floor('H')
这显然可以截断到小时并保留时区信息,问题出现在 dst 日到来时,例如 2017 年 10 月 29 日。给定以下代码:
dt1 = datetime.datetime(2017,10,29,0,1)
dt2 = datetime.datetime(2017,10,29,1,1)
df = pd.DataFrame([('whatever', dt1),('whatever',dt2)])
df[1] = df[1].dt.tz_localize('UTC').dt.tz_convert('Europe/Madrid')
df[1].dt.floor('H')
它产生给定的错误:
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\IPython\core\interactiveshell.py", line 2882, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-90-8319339cf020>", line 5, in <module>
df[1].dt.floor('H')
File "C:\Python27\lib\site-packages\pandas\core\base.py", line 210, in f
return self._delegate_method(name, *args, **kwargs)
File "C:\Python27\lib\site-packages\pandas\tseries\common.py", line 132, in _delegate_method
result = method(*args, **kwargs)
File "C:\Python27\lib\site-packages\pandas\tseries\base.py", line 101, in floor
return self._round(freq, np.floor)
File "C:\Python27\lib\site-packages\pandas\tseries\base.py", line 93, in _round
self._shallow_copy(result, **attribs))
File "C:\Python27\lib\site-packages\pandas\tseries\base.py", line 213, in _ensure_localized
result = result.tz_localize(self.tz)
File "C:\Python27\lib\site-packages\pandas\util\decorators.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:\Python27\lib\site-packages\pandas\tseries\index.py", line 1826, in tz_localize
errors=errors)
File "pandas\tslib.pyx", line 4380, in pandas.tslib.tz_localize_to_utc (pandas\tslib.c:75768)
AmbiguousTimeError: Cannot infer dst time from Timestamp('2017-10-29 02:00:00'), try using the 'ambiguous' argument
错误提示使用“歧义”参数,如果出现歧义,则需要做出预定义的决定。但是在我的数据框中,我不会说有这样的歧义,因为我有时区信息,并且在四舍五入后我仍然想要它。我宁愿避免歧义。
我也找到了解决办法:
df.loc[:, 1].values.astype('<M8[h]')
这通常适用于复杂的时区。例如尼泊尔的时区(亚洲/加德满都)是 GMT+5:45。同样,我想做的是将日期时间在本地时区截断到小时,在尝试上面的代码后,我观察到这会将其转换为 utc,然后截断,所以当它返回时本地化的日期时间我没有将它分组在确切的小时内,而是按每个 :45 分组。
代码:
dt1 = datetime.datetime(2017, 10, 29, 0, 1)
dt2 = datetime.datetime(2017, 10, 29, 1, 1)
df = pd.DataFrame([('whatever', dt1), ('whatever', dt2)])
df[1] = df[1].dt.tz_localize('Asia/Katmandu')
df[2] = df.loc[:, 1].values.astype('<M8[h]')
df[2].dt.tz_localize('UTC').dt.tz_convert('Asia/Katmandu')
我们得到以下结果:
0 2017-10-28 23:45:00+05:45
1 2017-10-29 00:45:00+05:45
Name: 2, dtype: datetime64[ns, Asia/Katmandu]
这证明我的问题的答案不是将日期时间转换为 'utc' 或时间戳,而是将它们整理并转换回本地化。
python datetime 的本机库有一个方法 replace,其中可以将分钟和秒信息替换为 0,但我在 pandas 中没有找到类似的日期时间列。我想找到一个不同的解决方案来逐行迭代,因为我的数据框很大。 关于如何根据此约束将 pandas 中的日期时间列截断为小时的任何想法?
【问题讨论】:
标签: python pandas datetime timezone truncate