创建填充NaN的numpy矩阵

293 投票
11 回答
415532 浏览
提问于 2025-04-15 15:50

我有以下代码:

r = numpy.zeros(shape = (width, height, 9))

这段代码创建了一个大小为 宽 x 高 x 9 的矩阵,里面全是零。不过,我想知道有没有什么简单的方法可以把这些值初始化为 NaN(不是一个数字)呢?

11 个回答

86

我比较了几种建议的替代方案,看看它们的速度如何。结果发现,对于足够大的向量或矩阵,除了 val * onesarray(n * [val]) 这两种方法,其他所有方法的速度差不多。

在这里输入图片描述


下面是用来生成这个图的代码:

import numpy
import perfplot

val = 42.0


def fill(n):
    a = numpy.empty(n)
    a.fill(val)
    return a


def colon(n):
    a = numpy.empty(n)
    a[:] = val
    return a


def full(n):
    return numpy.full(n, val)


def ones_times(n):
    return val * numpy.ones(n)


def list(n):
    return numpy.array(n * [val])


b = perfplot.bench(
    setup=lambda n: n,
    kernels=[fill, colon, full, ones_times, list],
    n_range=[2 ** k for k in range(20)],
    xlabel="len(a)",
)
b.save("out.png")
287

另一个选择是使用 numpy.full,这个功能在NumPy 1.8及以上版本中可以使用。

a = np.full([height, width, 9], np.nan)

这个方法非常灵活,你可以用任何你想要的数字来填充它。

402

在使用numpy进行向量操作时,你很少需要用到循环。

你可以创建一个未初始化的数组,然后一次性给所有的元素赋值:

>>> a = numpy.empty((3,3,))
>>> a[:] = numpy.nan
>>> a
array([[ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN]])

我对比了两种方法的时间,分别是 a[:] = numpy.nana.fill(numpy.nan),这是Blaenk提到的:

$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)"
10000 loops, best of 3: 54.3 usec per loop
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a[:] = np.nan" 
10000 loops, best of 3: 88.8 usec per loop

结果显示,ndarray.fill(..)的速度更快。另一方面,我喜欢numpy提供的方便用法,因为你可以一次性给整个切片赋值,这样代码的意图非常清晰。

需要注意的是,ndarray.fill是在原地进行操作的,所以 numpy.empty((3,3,)).fill(numpy.nan) 会返回 None

撰写回答