我有时区感知 UTC 格式的传入字符串,例如:
'2014-11-25 01:01:00+00:00'
并希望以本机本地化时区显示此信息 - 末尾没有 UTC 偏移位。
例如,上面的示例,对于美国/东部,应显示为:
'2014-11-24 20:01:00'
现在,我创建了一个小方法,它将接受一个输入字符串并执行此操作,吐回我想要的值。然而,它似乎效率低得可怕。我正在使用 pandas 进行数据操作,此方法以上述字符串格式应用于一整列时间序列字符串数据。通过交互式 shell 调用 apply 方法在 ~2 秒内完成执行,但奇怪的是,让代码在同一数据帧上按编译/解释的方式运行需要 15-20 秒。为什么?这就是我为数据帧/系列调用它的方式:
df['created_at'] = df['created_at'].apply(timeremap)
我是自学成才的,显然不是最好的程序员。请告诉我我能做些什么来简化这个过程。从谷歌搜索来看,python 中似乎有 5000 种转换时间的方法。我对任何模块/包都持开放态度,但最好希望在现有的库存 python 或熊猫中完成此操作。这样做的"正确方法"是什么?
这是我的小涂鸦:
from pandas.tseries.tools import parse_time_string
from pytz import timezone
import calendar
import datetime
def timeremap(intimestr, tz=timezone('US/Eastern')):
temp = parse_time_string(intimestr)[0]
loc = temp.astimezone(tz)
return str(dt(ut(loc)))
def dt(u):
return datetime.datetime.utcfromtimestamp(u)
def ut(d):
return calendar.timegm(d.timetuple())
如果为您提供了一个 csv 文件,其中包含按时间索引的数据:
time,value
2015-11-01 08:30:00+03:00,0
2015-11-01 08:45:00+03:00,1
2015-11-01 09:00:00+03:00,2
2015-11-01 09:15:00+03:00,3
2015-11-01 09:30:00+03:00,4
2015-11-01 09:45:00+03:00,5
2015-11-01 10:00:00+03:00,6
2015-11-01 10:15:00+03:00,7
您可以使用read_csv()
读取它并解析时间字符串,tz_convert()
将输入转换为目标时区:
#!/usr/bin/env python
import sys
import pandas
import pytz
filename = 'dataframe'
local_tz = pytz.timezone('America/New_York')
df = pandas.read_csv(filename, parse_dates=True, index_col=0)
df.index = df.index.tz_localize(pytz.utc).tz_convert(local_tz)
df.head().to_csv(sys.stdout)
df.head().to_csv(sys.stdout, date_format='%Y-%m-%d %H:%M:%S')
以下是每个索引值最初存储为 UTC 时间,没有关联的时区(转换前):
print(repr(df.index[0]))
# -> Timestamp('2015-11-01 05:30:00', tz=None)
或者,您可以在阅读过程中转换时间:
from dateutil.parser import parse
def parse_datetime(time_string, tz=local_tz):
return tz.normalize(parse(time_string).astimezone(tz))
df = pandas.read_csv(filename, date_parser=parse_datetime, index_col=0)
df.head().to_csv(sys.stdout)
df.head().to_csv(sys.stdout, date_format='%Y-%m-%d %H:%M:%S')
以下是每个索引值具有关联的时区:
print(repr(df.index[0]))
# -> Timestamp('2015-11-01 01:30:00-0400', tz='America/New_York')
输出
time,value
2015-11-01 01:30:00-04:00,0
2015-11-01 01:45:00-04:00,1
2015-11-01 01:00:00-05:00,2
2015-11-01 01:15:00-05:00,3
2015-11-01 01:30:00-05:00,4
time,value
2015-11-01 01:30:00,0
2015-11-01 01:45:00,1
2015-11-01 01:00:00,2
2015-11-01 01:15:00,3
2015-11-01 01:30:00,4
这两种方法产生相同的输出。
注意:如何使用date_format
来"抛弃"消除时间字符串歧义的 UTC 偏移量(美国/New_York时区的 DST 转换将于 2015 年 11 月 1 日结束)。