Как точно сэмплировать в питоне

На работе у меня есть необходимость: делать выборки каждые 0,08 секунды за 10 секунд.

Я использую цикл 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""

наконец, я получил 0 данных, я думаю, if float(time.time() -start_t) % float(0.08) == 0: не работает.

Я запутался, как установить условие для ввода кода выборки.

3 ответа

Самый простой способ - это использовать time.sleep:

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

Вы, вероятно, не получаете данных, потому что вы собираете время только в отдельные моменты. В эти моменты они никогда не станут идеальными, кратными 0,08.

Вы используете деление числа с плавающей запятой на число с плавающей запятой, и time.time() вернет длинное десятичное число, поэтому вы не получите никаких данных, потому что ваш результат всегда 0,00001234 или что-то в этом роде. Я думаю, что вы должны использовать раунд, чтобы получить 2 десятичного числа

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

Однако этот скрипт вернет около 27000 результатов за 10 секунд. Потому что у вас будет 0,08, 0,081,0,082 и т. Д., И все они будут выполнять вашу запись.

Поэтому я думаю, что вам лучше работать с решением Максимилиана Яниша (используя функцию сна). Я просто хочу объяснить, почему вы не нашли решения.

Надеюсь, что это полезно!

Вопрос: "Как точно образец в Python"

На работе ( Chongqing), у
меня есть необходимость: делать выборку каждые 0,08 секунд в течение 10 секунд.

Учитывая, что будет использоваться питон, для такой точной выборки потребуется пара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

Это , вероятно, никогда не будет правдой, поскольку проверка на равенство с плавающими типами должна быть очень точной.

попробуйте сделать что-то вроде:

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, которые вы ожидаете (и получите с помощью функции сна).

Другие вопросы по тегам