我有180,000行时间戳,我想解析成日期时间格式,如:
YYYY-MM-DD HH:MM:SS
以下是时间戳(注意前9小时内缺少前导零):
19-May-14 3:36:00 PM PDT
19-May-14 10:37:00 PM PDT
我一直使用parse_dates
作为pandas.read
的一部分来解析这些日期,但我发现这种方法很慢(通常约80秒)。我也尝试了dateutil
解析器,结果相似。
我想更快地解析时间戳,但我遇到时间戳中不同宽度的问题。我发现this SO solution似乎与我的问题非常相似,但未能使该方法适应不同长度的时间戳。
有人会建议对链接解决方案进行可行的调整,还是其他更好的方法?
谢谢
答案 0 :(得分:2)
此解决方案以附加链接中提供的accepted answer为基础,并假设时区由3个字符组成(并忽略其特定值)。
您可以根据它们在字符串开头的相对位置来提取年,月和日,如下所示:
month_abbreviations = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}
day = int(line[0:2])
month = month_abbreviations[line[3:6]]
year = 2000 + int(line[7:9]) # this should be adapted to your specific use-case
您可以根据它们在字符串末尾的相对位置提取分钟,秒和AM / PM,如下所示:
AM_PM = line[-6:-4]
second = int(line[-9:-7])
minute = int(line[-12:-10])
您可以根据其相对于字符串开头和结尾的位置来提取小时:
hour = int(line[10:-13])
然后您可以根据AM_PM值计算确切的小时数,如下所示:
hour = hour if AM_PM == 'AM' else hour + 12
根据我的计算,这比使用dict
略快,但不是很多:
hour_shifter = {(0, 'AM'): 0, (0, 'PM'): 12,
(1, 'AM'): 1, (1, 'PM'): 13,
...
(11, 'AM'): 11, (11, 'PM'): 23,
(12, 'AM'): 12}
hour = hour_shifter[(hour, AM_PM)]
现在您可以实例化datetime
对象:
datetime.datetime(year, month, day, hour, minute, second)
答案 1 :(得分:0)
使用正则表达式怎么样?你能提供你的数据文件进行测试吗?
patt = re.compile(r'(?P<day>\d\d)-(?P<month>\w+)-(?P<year>\d\d)'
r' (?P<hour>\d{1,2}):(?P<minute>\d\d):(?P<second>\d\d)'
r' (?P<noon>\w\w) (?P<tz>\w+)')
for date in dates:
res = patt.match(date)
print(res.groupdict())
然后将日,月,年等转换为整数,创建时区对象:
from pytz import timezone
tz = timezone(res.groupdict()['tz'])
答案 2 :(得分:0)
首先,一些问题。
这是我会尝试的。首先构建一些年份和月份的查找字典。
months = {'Jan': '01', 'Feb': '02', ... 'Dec': '12'}
years = {}
for i in range(50, 100):
years[str(i)] = '19' + str(i)
for i in range(0, 50):
years[str(i)] = '20' + str(i)
遍历每条记录和
可能明智地测试年份字典是否优于将两位数年份转换为整数,检查值,并根据您选择的截止值添加1900或2000。我希望字典能够获胜,但很难说。
答案 3 :(得分:0)
假设&#34; 14&#34;在您的日期字符串中对应于2014:
import datetime
month_abbr = {'Jan':1, 'Feb':2, 'Mar':3, 'Apr':4, 'May':5,'Jun':6,
'Jul':7, 'Aug':8, 'Sep':9, 'Oct':10, 'Nov':11, 'Dec':12
}
def format_date(date_str):
day, month, year = (date_str.split(' ')[0]).split('-')
hour, minute, sec = (date_str.split(' ')[1]).split(':')
return datetime.datetime(int(year)+2000, month_abbr[month],
int(day), int(hour), int(minute), int(sec))
date_str = '19-May-14 3:36:00 PM PDT'
#date_str = '19-May-14 10:37:00 PM PDT'
formatted_date = format_date(date_str)
print(formatted_date)
2014-05-19 03:36:00
datetime
对象的默认格式为YYYY-MM-DD HH:MM:SS,因此在这种情况下您不需要指定唯一格式。如果您将来这样做,请查看datetime中的strftime
功能。
如果&#34; 14&#34;可以在20世纪和2000年代之间切换,然后你需要(1)在摄取日期字符串之前知道这些信息,并且(2)调整上面的代码,以便在年份中添加1900或2000。