从txt文件到数组的时间戳

时间:2015-04-12 17:57:00

标签: python numpy

我有一个具有以下结构的txt文件:

"YYYY/MM/DD HH:MM:SS.SSS val1 val2 val3 val4 val5'

第一行看起来像:

"2015/02/18 01:05:46.004   13.737306807  100.526088432   -22.2937   2   5"

我无法将时间戳放入数组中。时间值用于比较来自不同文件的具有相同时间戳的数据,解析特定时间间隔的数据以及绘图用途。

这就是我现在所拥有的...除了时间信息:

dt=np.dtype([('lat', float), ('lon', float), ('height', float), ('Q', int), ('ns', int)]
a=np.loadtxt('tmp.pos', dt)

有关如何扩展 dt 以包含日期和时间列的任何建议吗?或者有比使用 numpy 中的 loadtext 更好的方法吗?

可以在此处找到该文件的示例:https://www.dropbox.com/s/j69l8oeqdm73q8y/tmp.pos

修改1

事实证明numpy.loadtxt采用了一个名为 converter 的参数来完成这项工作:

a = np.loadtxt(fname='tmp.pos', converters={0: strpdate2num('%Y/%m/%d'), 1: strpdate2num('%H:%M:%S.%f')})

这意味着a的前两列是'date'和'time',表示为浮点数。为了取回时间字符串,我可以做这样的事情(虽然可能有点笨拙):

In [441]: [datetime.strptime(num2date(a[i,0]).strftime('%Y-%m-%d')+num2date(a[i,1]).strftime('%H:%M:%S.%f'), '%Y-%m-%d%H:%M:%S.%f') for i in range(len(a[:,0]))]

给出:

Out[441]: [datetime.datetime(2015, 2, 18, 1, 5, 46)]

但是,不保留秒的小数部分。我做错了什么?

3 个答案:

答案 0 :(得分:0)

如果这是来自文本文件,则将其解析为文本可能更简单,除非您希望所有内容都以numpy数组结尾。例如:

>>> my_line = "2015/02/18 01:05:46.004   13.737306807  100.526088432   -22.2937   2   5"
>>> datestamp, timestamp, val1, val2, val3, val4, val5 = [v.strip() for v in my_line.split()]
>>> datestamp
'2015/02/18'
>>> timestamp
'01:05:46.004'

因此,如果您想迭代这些行的文件并获取每个ine的本机日期时间对象:

from datetime import datetime
with open('path_to_file', 'r') as my_file:
    for line in my_file:
        d_stamp, t_stamp, val1, val2, val3, val4, val5 = [v.strip() for v in my_line.split()]
        dt_obj = datetime.strptime(' '.join([d_stamp, t_stamp]), '%Y/%m/%d %H:%M:%S.%f')

答案 1 :(得分:0)

最好将时间字符串转换为timeStamp,并将值作为整数格式传递。整数也会加速你的比较。

import time
dt, ts = "2015/02/18 01:05:46.004".split()
year,mon,day = [int(d) for d in dt.split('/')]
hrs,mins,secs = [int(float(d)) for d in ts.split(':')]
timeStamp = time.mktime((year,mon,day,hrs,mins,secs,0,0,time.localtime()[8]))

答案 2 :(得分:0)

Pandas应该擅长这种事情。我没有专家,但在使用read_csvparse_date功能方面遇到了一些问题,但以下内容似乎运行得相当好和快:

import pandas as pd

names = ('date', 'time', 'lat', 'lon', 'height', 'Q', 'ns')
format = '%Y/%m/%d%H:%M:%S.%f'
df = pd.read_csv('tmp.pos', delim_whitespace=True, names=names)
df['datetime'] = pd.to_datetime(df['date'] + df['time'], format=format)

如果您想根据时间戳选择数据,可以将其设置为index of the dataframe

df.index = pd.to_datetime(df['date'] + df['time'], format=format)
print df['2015-02-18 2:30:00':'2015-02-18 2:30:10']

您还可以将时间列设置为索引,但似乎不支持仅使用时间直接切片:

format = '%H:%M:%S.%f'
df.index = pd.to_datetime(df['time'], format=format)
print df['2:30:00':'2:30:10']  # prints empty DataFrame

但是you can use the following

print df.between_time('2:30:00','2:30:10')