我有一个记录数据并需要一段时间才能完成的功能。在记录数据时,我想要一个按钮,按下该按钮后,会显示自数据采集开始以来已经过去了多少时间。
这可以在 Jupyter 中完成吗?
我遇到了问题,因为数据采集阻止了小部件激活,如果我尝试在后台运行小部件,它on_click
在数据采集完成之前不会收到事件。另一方面,如果我将数据采集发送到后台,那么一旦后台作业完成,数据就会丢失。
后台作业
from IPython.lib.backgroundjobs import BackgroundJobManager
from IPython.core.magic import register_line_magic
from IPython import get_ipython
jobs = BackgroundJobManager()
@register_line_magic
def background_job(line):
ip = get_ipython()
jobs.new(line, ip.user_global_ns)
定时器按钮
import ipywidgets as widgets
import time
def button_timer():
t0 = 0
button = widgets.Button(description="Measure time")
def action(b):
time_elapsed = time.perf_counter() - t0
display("Time elapsed: {}".format(time_elapsed))
button.on_click(action)
display(button)
t0 = time.perf_counter()
数据采集
import numpy as np
import pandas as pd
import time
def acquire(a=None):
time.sleep(10)
print("Done")
if a is None:
return np.linspace(0, 10, 10)
else:
a = np.linspace(0, 10, 10)
## Implementation 1
# This fails because the `on_click` event for the button only runs after the data has been acquired.
button_timer()
data = pd.DataFrame()
data['x'] = np.linspace(0, 10, 10)
data['y'] = acquire()
## Implementation 2
# As before, the `on_click` event isn't activated until after the data has been acquired.
%background_job button_timer()
data = pd.DataFrame()
data['x'] = np.linspace(0, 10, 10)
data['y'] = acquire()
## Implementation 3
# This one fails as the data isn't actually updated
button_timer()
data = pd.DataFrame()
data['x'] = np.linspace(0, 10, 10)
# I can't use the equal sign as that isn't supported by the background job.
# %background_job data['y'] = acquire()
# If I pass in the data I want, the DataFrame isn't updated (even after I wait for the background job to finish)
%background_job acquire(data['y'])
display(data)
如果一切都失败了,我想一个选择是有一个完全在浏览器中运行的纯 JavaScript 计时器。
不过,我想知道是否有办法在 Python 中执行此操作(如果可能的话,让(最后)测量的时间可以在笔记本的其余部分中以编程方式访问)。