如何使用数据框将EST转换为本地时间

时间:2019-05-28 21:43:35

标签: python pandas pytz

我正在尝试将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 :(“非原始日期时间(已设置tzinfo)”,“发生在索引0”)

我希望数据框中有一个名为“ local_timestamp”的新列,该列具有根据local_timezone列中的数据调整的时间戳。

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

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的代码

答案 1 :(得分:0)

您看到的错误看起来像是它的错误,因为您正在尝试对可感知tz的时间戳进行本地化。时间戳记中的'+00:00'表示它们是UTC(或类似的东西)感知的tz。

某些术语:单纯的日期/时间没有时区的概念,tz感知(或本地化)的日期/时间与特定时区相关联。本地化是指将tz原始日期/时间转换为tz感知的日期/时间。根据定义,您无法本地化支持tz的日期/时间:要么将其转换为天真然后本地化,要么直接转换为目标时区。

要将该列导入EST,请先转换为天真,然后本地化为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]

注意dtype中的“ 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()方法更改时区,将日期/时间转换为新时区。

这会产生pd.Timestamps列,其中包含多个时区,这在熊猫中很难处理。在日期/时间列上运行的大多数(也许是所有)熊猫函数都要求整个列具有相同的时区。

如果愿意,请转换为tz天真:

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转换或其他可能导致时间丢失/含糊不清的问题。