【发布时间】:2021-05-04 20:15:11
【问题描述】:
我正在做一个实时图像处理项目,需要更改一些参数。确切的细节并不重要,所以我只关注相关部分:
我有两个 Numpy 数组,其中一个是索引值列表(它有重复的索引),另一个是有效索引列表。
我尝试了np.intersect1D,但是它删除了重复的索引值,所以我尝试了np.isin 和np.in1d,这两个都需要大约 900 毫秒才能完成。
mask = np.isin(index_array,validRange)
new_index_array = index_array[mask]
new_coeff_array = coeff_array[mask]
我也尝试使用集合和字典作为成员资格测试的查找表,但它们也相当慢(大约 1.2 秒)。
作为最后的努力,我在 Cython 中实现了一个二进制搜索算法,该算法在 validRange 的排序版本上运行,但由于某种原因它会随机崩溃内核(使用完全相同的输入,它会在不同的点失败)。诚然,我正在使用的数组相当大(索引数组有 4,706,878 个元素,有效范围有 527,076 个元素),但即便如此,intersect1D 还是设法完成(接近 400 毫秒)。
尽管这不是常见的操作,但在更新设置时将实时系统停止大约 900 毫秒是不可接受的。
有没有什么方法可以加快这个过程,使其接近 intersect1d 的 300 到 400 毫秒的时间,而不需要删除重复的元素?我环顾了谷歌并尝试了一些不同的建议,但它们并没有真正改善。
附:我知道有些人想对使用np.where(x>y) 发表评论,但validRange 不是连续的,为方便起见被称为。例如,实际值可能是:[1,2,5,8,15,20,21],因此简单的条件无法解决此问题。
【问题讨论】:
-
如果时间成为问题,Python 可能不是正确的工具。
-
这正是我尝试使用 Cython 的原因,它以原生 C 速度运行,但提供了所有现有 python 包的便利
-
由于您似乎偏离了 2-4 倍,您或许可以使用多处理和共享内存来使用多个 CPU 内核。最新的共享内存非常快,现在许多 CPU 都有 4/8/12 个内核。见docs.python.org/3/library/multiprocessing.shared_memory.html
-
数组项的类型是什么?如果这是整数,它们有多大?他们有界吗?
validRange会随时间变化吗?如果您能提供一个更完整的示例来代表您的应用程序,那就太好了。 -
数值都是整数,不需要用浮点数逼近。范围在 0 到 857,476 (926*926) 之间。 validRange 确实会根据所选设置而改变,否则很容易将其构造为布尔数组并将其用作掩码,而不是从中生成掩码。不幸的是,为了提供一个更有意义的例子,我必须添加很多其他代码,这并不是这里真正的重点,我只想找到数组 B 中也存在的数组 A 的成员。
标签: python performance numpy