创建填充NaN的numpy矩阵
我有以下代码:
r = numpy.zeros(shape = (width, height, 9))
这段代码创建了一个大小为 宽 x 高 x 9
的矩阵,里面全是零。不过,我想知道有没有什么简单的方法可以把这些值初始化为 NaN
(不是一个数字)呢?
11 个回答
86
我比较了几种建议的替代方案,看看它们的速度如何。结果发现,对于足够大的向量或矩阵,除了 val * ones
和 array(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.nan
和 a.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
。