【问题标题】:Reading timestamps from a file and convert to ms从文件中读取时间戳并转换为 ms
【发布时间】:2013-06-01 04:05:09
【问题描述】:

我正在尝试用 Python 编写一个程序:

  • 将 .csv 文件作为输入
  • 读取第二行的时间戳
  • 将每个时间戳之间的时间差打印为 ms

当我在变量中写入时间戳时,代码可以工作,但是当我尝试使用文件作为输入时没有任何反应。程序运行,但没有任何内容打印到控制台。

这就是代码的样子:

import csv
import datetime
from Tkinter import Tk
from tkFileDialog import askopenfilename

Tk().withdraw()
toopen = askopenfilename(filetypes=[("Text file","*.txt")])

with open(toopen, 'rb') as f:
    reader = csv.reader(f, delimiter='\t')
    for row in reader:
        code = row[0]
        times = row[1].split()
        times = [datetime.datetime.strptime(x, "%H:%M:%S.%f") for x in times]
        for i in range(len(times) - 1):
            delta = times[i + 1] - times[i]
            print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)

这是我的输入文件的外观示例。

input23 13:13:05.674430
input47 13:13:06.623822
input52 13:13:07.573215
input66 13:13:08.522607

感谢任何帮助,因为我真的被困在这里! 谢谢

【问题讨论】:

  • 如果什么也没打印,那么你可能打开了一个空文件。
  • 我重新检查了文件,遗憾的是,不是问题。
  • 也许 row[1] 里面只有 一个 时间戳,没有空格?如果没有样本输入,这是无法判断的。您的代码看起来是正确的。
  • 为什么要打开二进制文件?
  • 添加了我的输入文件的示例。我尝试打开没有二进制文件的文件,但没有效果。

标签: python datetime csv


【解决方案1】:

为什么要拆分 row[1] 返回的内容?这只是一个时间戳,您正在从中制作 一个 项目的列表。

然后,在列表理解中,您将使用 one 时间戳迭代该列表,并从中创建一个 one datetime 实例的列表。

请注意,此时len(times) 为1。因此,在执行for i in range(len(times) - 1) 时,您实际上是在迭代range(0),这是一个空列表。

您真正想要的是将第二个 for 循环放在第一个之外。或者更好的是,将整个第一个 for row in reader: 循环替换为更简单的列表理解,如下所示:

reader = csv.reader(f, delimiter='\t')
times = [datetime.datetime.strptime(timestamp, "%H:%M:%S.%f") for _, timestamp in reader]

for i in range(len(times) - 1):
    delta = times[i + 1] - times[i]
    print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)

如果您愿意,您可以通过替换 range() 来改进剩余的 for 循环,并通过迭代成对的 datetime 实例及其后继者来改进索引 zip() 在列表中添加一个版本本身移动了一个地方,这可以说是更具可读性和pythonic:

reader = csv.reader(f, delimiter='\t')
times = [datetime.datetime.strptime(timestamp, "%H:%M:%S.%f") for _, timestamp in reader]

for time1, time2 in zip(times, times[1:]):
    delta = time2 - time1
    print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)

正如 J.F. Sebastian 所指出的,您可以通过使用 total_seconds() 而不是手动组合所有 3 个组件来更轻松地从 timedelta 获得总毫秒数。由于这已经返回了具有微秒分辨率的结果(它是一个浮点数),因此您只需乘以 1000 即可获得毫秒。如果你想要或不介意小数部分,你就完成了,否则你需要round() 和/或转换为int()

    print(delta.total_seconds() * 1000)

    print(int(delta.total_seconds() * 1000))

【讨论】:

  • 您可以使用1000 * delta.total_seconds() 来获取毫秒数。
  • 是的,我只是从问题中复制了该行,并没有费心检查它,因为它与问题无关。但你当然是对的,那是另一部分可以改进的地方。
  • @J.F.Sebastian 感谢您的建议,并进行了相应的编辑。
  • 谢谢!完美运行!当我看不到错误时,您的解释很好地指出了我的代码有什么问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-07-29
  • 2012-04-19
  • 1970-01-01
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 2016-02-13
相关资源
最近更新 更多