繁体   English   中英

在大型 numpy 数组中插入 NaN 值

[英]Interpolate NaN values in a large numpy array

我想替换 numpy 数组(63*479060)中的所有 NaN 值。 我提到了这个问题Interpolate NaN values in a numpy array并尝试了以下代码,但它没有给出插值的结果(因为我认为数组的大小很大)。

a = np.arange(30180780).reshape((63, 479060)).astype(float)
a[np.random.randint(2, size=(63, 479060)).astype(bool)] = np.NaN
x, y = np.indices(a.shape)
interp = np.array(a)
interp[np.isnan(interp)] = griddata(
(x[~np.isnan(a)], y[~np.isnan(a)]), 
a[~np.isnan(a)],                    
(x[np.isnan(a)], y[np.isnan(a)]))   

有没有一种有效的方法可以在如此大的数组中插入 NaN? 非常感谢。

非结构化网格上的插值结果非常昂贵 Scipy 代码经过一些优化,因为它是用 Cython 编写的,并且在内部使用QHull库。 该算法首先通过对输入数据进行三角剖分来构造插值,然后对每个三角形执行线性重心插值。 尽管使用了专门的本地 C 库,但在这种情况下, Delaunay 三角剖分(在O(n log n)时间内运行)的计算非常慢:几乎所有时间都在计算它。

QHull 执行的代码显然是次优的,因为它是顺序的,没有使用 SIMD 指令进行矢量化,并且二进制文件不能从 FMA 指令集中受益。 它也是通用的:没有专门针对 2D 案例进行优化。 优化的特定实现当然可以快得多,但高效实现很难/乏味(即使对于非常熟练的开发人员也是如此)。 * 使用更积极的编译器优化重新编译 QHull 库肯定会有所帮助(如-O3-march=native )。

另一种可能的优化包括将空间分成 N 个部分,并在N 个单独的线程中独立地对每个部分执行线性插值。 这可能会更快,因为 SciPy 在执行此计算时禁用全局解释器锁 (GIL),而 GIL 通常会阻止线程加速计算绑定操作。 话虽如此,正确分割空间并不容易,因为某些点可能位于边界上。 在实践中,需要在非结构化网格的每个部分中包含一个额外的重影区域才能正确执行此操作(不幸的是,这并非易事)。

另一种解决方案在于使用近似值 实际上,您可以使用Ball-Tree 算法(在 ScipPy 中实现)找到 K 近点,然后根据收集的点执行线性插值。

最后,最后一个解决方案是使用可能更优化的库(如 CGAL)重新实现 SciPy 方法,CGAL 已知速度非常快(有一个 Python 绑定,但我不确定它的性能)。 它可以很容易地计算非结构化网格的三角剖分(如果优化应该需要几秒钟)。 然后,可以使用 KD 树将分面与点进行匹配。 话虽如此, CGAL 似乎直接支持插值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM