如何使用 Dataframe 将 EST 转换为本地时间

How to Convert EST to Local Time with Dataframe

我正在尝试将 EST 中的时间戳转换为 pandas 数据帧中的各种本地化时间戳。我有一个带有 EST 时间戳的数据框和一个需要将它们转换成的时区。

我知道已经有多个线程讨论了此类主题。但是,它们要么以 UTC 开始,要么我无法用我的数据进行复制。

写之前咨询了:How to convert GMT time to EST time using python

我导入了数据:

import pandas
import datetime as dt
import pytz 

transaction_timestamp_est         local_timezone

2013-05-28 05:18:00+00:00         America/Chicago
2013-06-12 05:23:20+00:00         America/Los_Angeles
2014-06-21 05:26:26+00:00         America/New_York

我转换为日期时间并创建了以下函数:

df.transaction_timestamp_est = 
pd.to_datetime(df.transaction_timestamp_est)


def db_time_to_local(row):

    db_tz = pytz.timezone('America/New_York')
    local_tz = pytz.timezone(row['local_timezone'])

    db_date = db_tz.localize(row['transaction_timestamp_est'])
    local_date = db_date.astimezone(local_tz)

    return local_date

我运行它在这里:

df['local_timestamp'] = df.apply(db_time_to_local, axis=1)

并得到这个错误:

ValueError: ('Not naive datetime (tzinfo is already set)', 'occurred at index 0')

我希望数据框中有一个名为 'local_timestamp' 的新列,它根据 local_timezone 列中的数据调整了时间戳。

感谢任何帮助!

from datetime import datetime, time, date
from pytz import timezone, utc

tz = timezone("Asia/Dubai")
d = datetime.fromtimestamp(1426017600,tz)
print d
midnight = tz.localize(datetime.combine(date(d.year, d.month, d.day),time(0,0)), is_dst=None)
print int((midnight - datetime(1970, 1, 1, tzinfo=utc)).total_seconds())

基于 python - datetime with timezone to epoch

中的代码

您看到的错误看起来像是因为您正在尝试本地化 tz-aware 时间戳。您的时间戳中的 '+00:00' 表示这些是 tz-aware,UTC(或类似时间)。

一些术语:天真的 date/time 没有时区概念,tz-aware(或本地化)与特定时区相关联。本地化是指将 tz-naive date/time 转换为 tz-aware。根据定义,您不能本地化 tz-aware date/time:您要么将其转换为 naive 然后本地化,要么直接转换为目标时区。

要将该列转换为 EST,请转换为 naive,然后本地化为 EST:

In [98]: df['transaction_timestamp_est'] = df['transaction_timestamp_est'].dt.tz_localize(None).dt.tz_localize('EST') 
In [99]: df
Out [99]:

0   2013-05-28 05:18:00-05:00
1   2013-06-12 05:23:20-05:00
2   2014-06-21 05:26:26-05:00
Name: transaction_timestamp_est, dtype: datetime64[ns, EST]

注意数据类型中的 'EST'。 然后,您可以将每个时间戳转换为其目标时区:

In [100]: df['local_ts'] = df.apply(lambda x: x[0].tz_convert(x[1]), axis=1)                                        

In [101]: df                                                                                                        
Out[101]: 
  transaction_timestamp_est       local_timezone                   local_ts
0 2013-05-28 05:18:00-05:00      America/Chicago  2013-05-28 05:18:00-05:00
1 2013-06-12 05:23:20-05:00  America/Los_Angeles  2013-06-12 03:23:20-07:00
2 2014-06-21 05:26:26-05:00     America/New_York  2014-06-21 06:26:26-04:00

解释一下:第一列的每个元素都是pd.Timestamp类型。它的 tz_convert() 方法改变了它的时区,将 date/time 转换为新时区。

这会产生一列 pd.Timestamps 混合时区,这在 pandas 中处理起来很痛苦。对 date/time 的列进行操作的大多数(可能是全部)pandas 函数要求整个列具有相同的时区。

如果您愿意,请转换为 tz-naive:

In [102]: df['local_ts'] = df.apply(lambda x: x[0].tz_convert(x[1]).tz_convert(None), axis=1)                                                      

In [103]: df                                                                                                                                       
Out[103]: 
  transaction_timestamp_est       local_timezone            local_ts
0 2013-05-28 05:18:00-05:00      America/Chicago 2013-05-28 10:18:00
1 2013-06-12 05:23:20-05:00  America/Los_Angeles 2013-06-12 10:23:20
2 2014-06-21 05:26:26-05:00     America/New_York 2014-06-21 10:26:26

如果您的数据允许,最好尝试将时间戳(或索引)列保留在单个时区中。 UTC 通常是最好的,因为它没有 DST 转换或其他可能导致丢失/模糊时间的问题,就像大多数其他时区一样。