如何在熊猫中截断/舍入到小时本地化的日期时间列



我想在熊猫蟒蛇中截断/四舍五入到小时本地化的日期时间列。例如,如果我有 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:Python27libsite-packagesIPythoncoreinteractiveshell.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:Python27libsite-packagespandascorebase.py", line 210, in f
return self._delegate_method(name, *args, **kwargs)
File "C:Python27libsite-packagespandastseriescommon.py", line 132, in _delegate_method
result = method(*args, **kwargs)
File "C:Python27libsite-packagespandastseriesbase.py", line 101, in floor
return self._round(freq, np.floor)
File "C:Python27libsite-packagespandastseriesbase.py", line 93, in _round
self._shallow_copy(result, **attribs))
File "C:Python27libsite-packagespandastseriesbase.py", line 213, in _ensure_localized
result = result.tz_localize(self.tz)
File "C:Python27libsite-packagespandasutildecorators.py", line 91, in wrapper
return func(*args, **kwargs)
File "C:Python27libsite-packagespandastseriesindex.py", line 1826, in tz_localize
errors=errors)
File "pandastslib.pyx", line 4380, in pandas.tslib.tz_localize_to_utc (pandastslib.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"或时间戳,而是截断它们并将它们转换回本地化。

pythondatetime的本机库有一个方法替换,其中可以替换 0 的分钟和秒信息,但我在 pandas 中没有找到类似的东西。我想找到一个不同的解决方案来逐行迭代,因为我的数据帧非常大。 关于如何根据此约束将熊猫中的日期时间列截断为小时的任何想法?

我观察到这会将其转换为 UTC,然后截断

为了大家的利益,我在将日期截断为特定格式时遇到了同样的问题。astype函数将日期转换为UTC,这就是为什么如果您尝试截断以前转换为另一个时区的日期,它不起作用。

最有效的解决方案(也是快速运行的解决方案)是按如下方式使用to_period函数:

# Comverting string column to datetime with UTC by default
df['column_name'] = pd.to_datetime(df['column_name'], infer_datetime_format=True, utc=True)
# Converting to an specific time zone
df['column_name'] = df['column_name'].dt.tz_convert('Europ
e/Amsterdam')
# Removing time offset if needed
df['column_name'] = df['column_name'].dt.tz_localize(None)
# Truncating the datetime
df['column_name'] = df['column_name'].dt.to_period('M').dt.to_timestamp()

如果您想使用另一个句点,请查看此网址:https://pandas.pydata.org/docs/user_guide/timeseries.html#timeseries-offset-aliases

最新更新