进度条#

基本进度条#

进度条是了解某个计算可能需要多长时间的一个很好的方式。Vaex中负责计算或聚合的大多数方法都支持显示进度条。显示进度条非常简单:

[1]:
import vaex

df = vaex.datasets.taxi()
df.total_amount.mean(progress=True)
mean [########################################] 100.00% elapsed time  :     0.09s =  0.0m =  0.0h

[1]:
array(11.6269824)

如果您在Jupyter笔记本中,可以传递progress='widget'以获得由ipywidgets提供的更美观的进度条:

[2]:
df.payment_type.unique(progress='widget')
[2]:
['CRD', 'CSH']

基于Rich的进度条#

使用基于Rich的进度条,我们可以将这个想法提升到一个新的水平。使用Rich,用户可以看到进度条的树状结构,这让他们了解Vaex在内部做了什么,以及每个步骤需要多长时间。这棵树中的每个叶子都是一个Task,而节点则用于逻辑上分组任务。例如,在下面的示例中,最后一个名为‘mean’的节点使用了均值聚合,这创建了两个任务:求和和计数聚合。

[3]:
with vaex.progress.tree('rich', title="My Vaex computations"):
    result_1 = df.groupby('passenger_count', agg='count')
    result_2 = df.groupby('vendor_id', agg=vaex.agg.sum('tip_amount'))
    result_3 = df.tip_amount.mean()

在最后一列(括号内)我们还看到Vaex计算所有结果需要对数据进行多少次遍历。最后两个任务在第五次遍历中一起完成。

如果我们出于性能原因想要在单次数据遍历中完成所有计算,我们可以使用Vaex的异步方式,通过添加延迟参数(更多详情请参见使用Vaex进行异步编程)。

[4]:
with vaex.progress.tree('rich', title="My Vaex computations"):
    result_1 = df.groupby('passenger_count', agg='count', delay=True)
    result_2 = df.groupby('vendor_id', agg=vaex.agg.sum('tip_amount'), delay=True)
    result_3 = df.tip_amount.mean(delay=True)
    df.execute()
result_1 = result_1.get()
result_2 = result_2.get()
result_3 = result_3.get()

我们看到所有的计算都是在数据的一次遍历中完成的,在这种情况下稍微快一些,因为我们不受IO限制。在较慢的磁盘或较慢的格式(例如parquet)上,这种差异会更大。

将此与缓存功能结合使用,我们可以清楚地看到对后续计算的影响以及Vaex的效率:

[5]:
vaex.cache.disk(clear=True)  # turn on cache, and delete all cache entries

with vaex.progress.tree('rich', title="Warm up cache"):
    result_1 = df.groupby('passenger_count', agg='count', delay=True)
    result_2 = df.groupby('vendor_id', agg=vaex.agg.sum('tip_amount'), delay=True)
    df.execute()


with vaex.progress.tree('rich', title="My Vaex computations"):
    result_1 = df.groupby('passenger_count', agg='count', delay=True)
    result_2 = df.groupby('vendor_id', agg=vaex.agg.sum('tip_amount'), delay=True)
    result_3 = df.tip_amount.mean(delay=True)
    df.execute()
vaex.cache.off();