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