【问题标题】:Why is datetime.datetime skipping repeating and skipping time values?为什么 datetime.datetime 跳过重复和跳过时间值?
【发布时间】:2017-03-01 21:56:31
【问题描述】:

我有一段代码从 LabJack 和接近传感器接收数据。它在无限循环上运行,记录电压值,直到用户停止它。

但是,我注意到一些奇怪的事情,我的 x 轴时间值列表似乎比我的绘图分辨率显示的数字多得多。即,我的 x 轴时间值似乎仅每 10 毫秒绘制一个点,但我的程序每 3.8 秒收集 5000 个数据点,这应该等于不到每 1 毫秒的数据点。

然后我查看了我的数据,发现了问题。下面是我的 x 轴值列表中的前几十个数字。

[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.00999999999999801, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.020000000000003126, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.030000000000001137, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.03999999999999915, 0.04999999999999716, 0.04999999999999716,... etc.

由于某种原因,代码重复每个时间值 10 次或更多次,然后将值增加 10 毫秒并执行相同的操作。下面是记录电压和时间的代码循环。相关行是我定义self.t0tcurrt 的行。

def startData(self):
    print "Starting data collection"
    self.t0 = float(datetime.now().strftime('%S.%f')[:-3])
    while True:
        with self.data_lock:
            while not self.data_loop:
                ain0bits, = self.d.getFeedback(u3.AIN(0))
                tcurr = datetime.now()
                volts = self.d.binaryToCalibratedAnalogVoltage(ain0bits, isLowVoltage = False, channelNumber = 0)
                t = float(tcurr.strftime('%S.%f')[:-3]) - self.t0    #note, approximate - will be just after voltage was read.
                self.tdict.append(t)
                self.vdict.append(volts)
                self.i += 1

感谢任何帮助!

【问题讨论】:

  • 您的系统对于datetime.now() 的分辨率实际上是否超过厘秒?
  • 您是说tdict 中的条目数与vdict 相比不同?
  • @user2357112 我该如何检查?不是所有的计算机都应该有至少毫秒的分辨率吗?是否有另一个 Python 包可以让我获得那种时间分辨率?我不需要精确的绝对时间,我需要精确的相对时间,就像秒表而不是时钟。
  • @Prophecies 是的,vdict 具有来自 LabJack 数据采集的电压值。这些值看起来不错,它们不会重复或任何东西。
  • @RBuntu:如果您使用的是 Python 3,我会推荐 time.perf_counter()。既然你不是,timeit.default_timer() 可能是你最好的时间选择。

标签: python python-2.7 datetime


【解决方案1】:

看起来您的每个循环都以低于 datetime.datetime 的最小分辨率完成。我编写了简单的脚本来查看是否记录了亚毫秒分辨率。看起来是这样。此外,由于您只测量经过的时间并且不需要高级格式、时区等,因此使用time.time() 将比datetime 模块提供更好的时间分辨率。

测试 1

import time
lst1 = list()
BIG_NUM = 10000
for a in range(10):
    for a in range(BIG_NUM):
        pass
lst1.append(time.time())

测试 2

import datetime
lst2 = list()
BIG_NUM = 10000
for a in range(10):
    for a in range(BIG_NUM):
        pass
lst2.append(datetime.datetime.now().strftime('%S.%f')[:-3])

即使 BIG_NUM 非常小,在 lst1 中记录的次数也在增加,但在 lst2 中有重复的条目。但是如果你完全移除内部循环,可能会有一些重复的条目,仅仅是因为操作完成的时间小于 time.time() 提供的分辨率

TL;DR:使用time.time()。如果仍有重复条目,则内部的操作发生的速度比您可用的最高分辨率时间要快。

【讨论】:

  • 我用time.time() 尝试了这个,出于某种原因,它在第一次尝试时有效,但从第二次构建开始,它遇到了与以前相同的问题。您是否获得了低于 10 毫秒的分辨率,或者这些值是否仅在 1 毫秒以下开始重复?
  • 是的,仅在 1ms 以下重复。在我的第二次测试中,我遇到了和你类似的问题
  • 我下载了一些名为“TimerToolV3”的第三方软件,它位于通知区域,可将系统时钟分辨率提高到 0.5 毫秒。代码现在可以工作了,我只是希望有一种方法可以在 Python 2.7 中实现。
猜你喜欢
  • 2021-04-09
  • 2021-03-19
  • 2015-05-06
  • 2013-02-08
  • 2016-12-13
  • 2014-09-24
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多