【发布时间】:2021-09-03 08:19:22
【问题描述】:
假设我有一个数据流,其中一次检索单个数据点:
import numpy as np
def next_data_point():
"""
Mock a data stream. Data points will always be a positive float
"""
return np.random.uniform(0, 1_000_000, dtype='float')
我需要能够更新 NumPy 数组并跟踪该流中迄今为止的前 K 个最小值(或者直到用户决定何时可以通过某些 check_stop_condition() 函数停止分析) .假设我们想从流中捕获前 1,000 个最小值,那么实现此目的的简单方法可能是:
k = 1000
topk = np.full(k, fille_value=np.inf, dtype='float')
while check_stop_condition():
topk[:] = np.sort(np.append(topk, next_data_point()))[:k]
这很好用,但效率很低,如果重复数百万次可能会很慢,因为我们是:
- 每次都创建一个新数组
- 每次都对串联的数组进行排序
所以,我想出了一种不同的方法来解决这两个低效率问题:
k = 1000
topk = np.full(k, fille_value=np.inf)
while check_stop_condition():
data_point = next_data_point()
idx = np.searchsorted(topk, data_point)
if idx < k:
topk[idx : -1] = topk[idx + 1 :]
top[idx] = data_point
在这里,我利用np.searchsorted() 替换np.sort 并快速找到下一个数据点的插入点idx。我相信np.searchsorted 使用某种二进制搜索并假设初始数组首先被预先排序。然后,我们在topk 中移动数据以适应并插入新数据点当且仅当idx < k。
我还没有看到任何地方都这样做过,所以我的问题是,是否可以做些什么来提高效率?尤其是在我在 if 语句中进行转换的方式。
【问题讨论】:
标签: python arrays performance numpy