0

在工作中,我有一个需求:在 10 秒内每 0.08 秒采样一次。

我使用while循环,但它失败了。

import time
start_t =time.time()
while time.time() -start_t <=10:
    if float(time.time() -start_t) % float(0.08) == 0:
       """do sample record""

最后,我根本没有数据,我认为这if float(time.time() -start_t) % float(0.08) == 0:不起作用。

我很困惑如何设置输入采样代码的条件。

4

4 回答 4

3

最简单的方法是使用time.sleep

from time import sleep
for i in range(125):
    """do sample record"""
    sleep(0.08)

您可能没有得到任何数据,因为您只在离散的时刻收集时间。在这些时刻,它们永远不会是 0.08 的完美倍数。

于 2019-07-11T09:41:15.223 回答
1

Q“如何在python中准确采样”

在工作重庆
我有一个需求:10秒内每0.08秒采样一次。

鉴于要使用,如此精确的采样将需要signal.signal()unix 系统上的一对处理程序,

import signal

#------------------------------------------------------------------
# DEFINE HANDLER, responsible for a NON-BLOCKING data-acquisition
#------------------------------------------------------------------
def aSIG_HANDLER( aSigNUM, aPythonStackFRAME ):
    ... collect data ...
    return

#------------------------------------------------------------------    
# SET THE SIGNAL->HANDLER MAPPING
#------------------------------------------------------------------
signal.signal( signal.SIGALM, aSIG_HANDLER )

#------------------------------------------------------------------
# SET THE INTERVAL OF SIGNAL-ACTIVATIONS
#------------------------------------------------------------------
signal.setitimer( signal.ITIMER_REAL, seconds  = 0,      # NOW WAIT ZERO-SECONDS
                                      interval = 0.08    #     FIRE EACH 80 [ms]
                  )

#------------------------------------------------------------------
# ... more or less accurately wait for 10 seconds, doing NOP-s ...
#------------------------------------------------------------------

#----------------------------------------------------------------
# AFTER 10 [s] turn off the signal.ITIMER_REAL activated launcher
#----------------------------------------------------------------
signal.setitimer( signal.ITIMER_REAL, seconds  = 0,      # NOW WAIT ZERO-SECONDS
                                      interval = 0.0     #     STOP SENDING SIGALM-s
                  )

或者,
对于基于 Windows 的系统,
有机会调整(并微调到自校正,即不漂移)Tkinter基于采样器,如答案所示。

class App():

    def __init__( self ):
        self.root = tk.Tk()
        self.label = tk.Label( text = "init" )
        self.label.pack()
        self.sampler_get_one()          # inital call to set a scheduled sampler
        self.root.lower()               # hide the Tk-window from GUI-layout
        self.root.mainloop()

    def sampler_get_one( self ):
        # \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
        #
        # DEMO to show real plasticity of the Tkinter scheduler timing(s)
        #
        # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
        ... review a drift of the activation + adapt the actual delay for a next .after()
        #    SET .after()  vv-----------# re-calculate this value to adapt/avoid drifting
        self.root.after(   80,          # re-instate a next scheduled call,
                         self.sampler_get_one
                         )              # .after a given ( self-corrected ) delay in [ms]
        #-------------------------------#-NOW--------------------------------------------
        ... acquire ... data ...        # best in a non-blocking manner & leave ASAP
于 2020-04-13T22:36:11.187 回答
1

您使用浮点数除以浮点数,并且 time.time() 将返回一个长十进制数,因此您不会得到任何数据,因为您的结果总是 0.00001234 或类似的东西。我认为你应该使用round来获得2个十进制数

temp = time.time()-start_t
if round(temp,2) % 0.08 == 0:
   """do sample record"""

但是,此脚本将在 10 秒内返回大约 27000 个结果。因为您将拥有 0.08、0.081、0.082 等,它们都会完成您的录音工作。

所以我认为你应该使用 Maximilian Janisch 解决方案(使用睡眠功能)更好。我只想解释为什么你没有解决方案。

希望这有帮助!


结语:

恕我直言,提议的代码非常危险且具有误导性。
只需测试它变得多么幼稚:绝不会
8.00 % 0.08产生,而应该提供 - 条件并取样,如果它不是实数 IEEE-754 处理中的(已知)陷阱。为了了解灾难的范围,请尝试:+ 将其与上面定义的任务获取的 125 个样本进行比较。获得 8 个样本而不是 125 个@常规样本,12.5 [Hz] 采样远非解决方案!– user3666197 22 小时前0.07999999999999984== 0
if

sum( [ round( i * 0.08, 2 ) % 0.08 == 0 for i in range( 126 ) ] )



@user3666197 哇,一个非常清楚的解释,我想我应该删除这个答案以避免将来产生误导。谢谢!– 托比 5 小时前


最好不要删除答案,因为它记录了永远不会做的事情,
这对社区具有特定价值
- 最好提及理由,不要在任何现实生活系统中使用这种方法。

整体的教训是积极的
——所有人都学到了朝着更好的系统设计迈出的下一步。我祝你一切顺利,伙计!– user3666197 4 分钟前

于 2019-07-11T09:56:30.410 回答
0

这可能永远不会完全正确,因为像这样检查浮点数的相等性需要非常精确。

尝试做类似的事情:

start_t =time.time()
looped_t = start_t
while time.time() - start_t <= 10:
    if time.time() - looped_t >= 0.08:
       looped_t = time.time()
       """do sample record""

Maximillian 的睡眠回答也很好,除非您的采样需要大量时间(数百秒),那么您将不会停留在 10 秒要求附近。

它还取决于您的优先级,因为此方法最多提供 124 个样本,而不是您期望的确切 125 个样本(并且使用 sleep 功能)。

于 2019-07-11T10:05:43.057 回答