有效地转换pandas数据帧中的时区

时间:2017-12-14 21:23:07

标签: python pandas datetime timezone

我有一个大型的pandas数据帧(数千万行),其中包括一个UTC时间和时区列。我想根据这两个其他列创建一个包含行的本地时间的列。

我最初的尝试是使用df.apply处理我正在测试的小样本,但速度非常慢,并且不足以处理整个数据:

df['LoginTimeLocal'] = \ 
    df.apply(lambda row: row.LoginTimeUtc.tz_localize('UTC').tz_convert(row.TimeZoneCode))

这会导致添加一个新列,其中包含当地时间的日期时间,以及时区信息。

我遇到了this回答,提供了一种有效的,矢量化的方式来做类似的事情。我重新使用此代码来执行我想要的操作,但它似乎仅在新列仅包含具有相同时区的日期(或没有时区信息)时才起作用。这是我的代码:

# localize all utc dates
df['LoginTimeUtc'] = df['LoginTimeUtc'].dt.tz_localize('UTC')

# initialize LoginTimeLocal column (probably not necessary)
df['LoginTimeLocal'] = df['LoginTimeUtc']

# for every time zone in the data
for tz in df.TimeZoneCode.unique():
    mask = (df.TimeZoneCode == tz)

    # make entries in a new column with converted timezone
    df.loc[mask, 'LoginTimeLocal'] = \ 
        df.loc[mask,'LoginTimeLocal'].dt.tz_convert(tz)

如果我在仅包含来自一个时区的日期(即len(df.TimeZoneCode.unique()) = 1)的数据样本上运行此操作,则它可以正常工作。只要数据框中有两个或更多时区,我就会得到一个ValueError: incompatible or non tz-aware value

谁能看到这里出了什么问题?

1 个答案:

答案 0 :(得分:1)

演示:

来源DF:

In [11]: df
Out[11]:
             datetime         time_zone
0 2016-09-19 01:29:13    America/Bogota
1 2016-09-19 02:16:04  America/New_York
2 2016-09-19 01:57:54      Africa/Cairo
3 2016-09-19 11:00:00    America/Bogota
4 2016-09-19 12:00:00  America/New_York
5 2016-09-19 13:00:00      Africa/Cairo

解决方案:

In [12]: df['new'] =  df.groupby('time_zone')['datetime'] \
                        .transform(lambda x: x.dt.tz_localize(x.name))

In [13]: df
Out[13]:
             datetime         time_zone                 new
0 2016-09-19 01:29:13    America/Bogota 2016-09-19 06:29:13
1 2016-09-19 02:16:04  America/New_York 2016-09-19 06:16:04
2 2016-09-19 01:57:54      Africa/Cairo 2016-09-18 23:57:54
3 2016-09-19 11:00:00    America/Bogota 2016-09-19 16:00:00
4 2016-09-19 12:00:00  America/New_York 2016-09-19 16:00:00
5 2016-09-19 13:00:00      Africa/Cairo 2016-09-19 11:00:00