初始化和填充numpy数组的最佳方法?

31 投票
5 回答
45846 浏览
提问于 2025-04-17 22:22

我想初始化并填充一个 numpy 数组。有什么好的方法吗?

这个方法按我预期的工作:

>>> import numpy as np
>>> np.empty(3)
array([ -1.28822975e-231,  -1.73060252e-077,   2.23946712e-314])

但这个方法就不行:

>>> np.empty(3).fill(np.nan)
>>> 

什么都没有?

>>> type(np.empty(3))
<type 'numpy.ndarray'>

我觉得 np.empty() 这个调用返回的对象类型是对的,所以我不明白为什么 .fill() 不起作用?

先把 np.empty() 的结果赋值给一个变量就可以正常工作:

>>> a = np.empty(3)
>>> a.fill(np.nan)
>>> a
array([ nan,  nan,  nan])

为什么我需要先赋值给一个变量才能使用 np.fill()?我是不是错过了更好的方法?

5 个回答

0

如果你不介意使用 None,你可以这样做:

a = np.empty(3, dtype=object)
2

为了将来参考,乘以 np.nan 之所以有效,是因为 np.nan 的数学特性。对于一个普通的值 N,你需要使用 np.ones() * N,这和被接受的答案类似,但从速度上来说,这并不是一个特别好的选择。

最佳选择是 np.full(),正如之前提到的。如果你无法使用这个,np.zeros() + Nnp.ones() * N 更好,而 np.empty() + Nnp.empty() * N 则不太合适。需要注意的是,当 Nnp.nan 时,np.zeros() + N 也能正常工作。

%timeit x = np.full((1000, 1000, 10), 432.4)
8.19 ms ± 97.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.zeros((1000, 1000, 10)) + 432.4
9.86 ms ± 55.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.ones((1000, 1000, 10)) * 432.4
17.3 ms ± 104 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x = np.array([432.4] * (1000 * 1000 * 10)).reshape((1000, 1000, 10))
316 ms ± 37.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
3

我觉得这个很容易记住:

numpy.array([numpy.nan]*3)

出于好奇,我计时了一下,发现@JoshAdel的回答@shx2的回答在处理大数组时都比我的快得多。

In [34]: %timeit -n10000 numpy.array([numpy.nan]*10000)
10000 loops, best of 3: 273 µs per loop

In [35]: %timeit -n10000 numpy.empty(10000)* numpy.nan
10000 loops, best of 3: 6.5 µs per loop

In [36]: %timeit -n10000 numpy.full(10000, numpy.nan)
10000 loops, best of 3: 5.42 µs per loop
44

你也可以试试:

In [79]: np.full(3, np.nan)
Out[79]: array([ nan,  nan,  nan])

相关的文档:

Definition: np.full(shape, fill_value, dtype=None, order='C')
Docstring:
Return a new array of given shape and type, filled with `fill_value`.

不过我觉得这个功能可能只在numpy 1.8及以上版本中有。

31

np.fill 是一个用来直接修改数组的函数,它会在原地改变数组的内容,并且返回的结果是 None。所以,如果你把这个结果赋值给一个变量,这个变量的值就会变成 None

另外一种方法是使用一个会返回 nan 的表达式,比如:

a = np.empty(3) * np.nan

撰写回答