将numpy矩阵初始化为零或一个以外的值

时间:2009-11-10 00:10:07

标签: python numpy

我有以下代码:

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

它创建一个用零填充的宽度x高度x 9矩阵。相反,我想知道是否有一种函数或方法将它们初始化为NaN。

有吗?无需诉诸手动循环等?

由于

8 个答案:

答案 0 :(得分:212)

你很少需要在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(..)作为更快的选择。 OTOH,我喜欢numpy的便利实现,你可以在那里为整个切片分配值,代码的意图非常明确。

答案 1 :(得分:119)

另一种选择是使用numpy.full,这是NumPy 1.8 +

中提供的选项
a = np.full([height, width, 9], np.nan)

这非常灵活,您可以使用您想要的任何其他数字填充它。

答案 2 :(得分:34)

我比较了建议的速度替代方案,并发现,对于足够大的矢量/矩阵来填充,除val * onesarray(n * [val])之外的所有替代方案都同样快。

enter image description here

重现情节的代码:

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])


perfplot.show(
    setup=lambda n: n,
    kernels=[fill, colon, full, ones_times, list],
    n_range=[2**k for k in range(20)],
    logx=True,
    logy=True,
    xlabel='len(a)'
    )

答案 3 :(得分:25)

您熟悉numpy.nan吗?

您可以创建自己的方法,例如:

def nans(shape, dtype=float):
    a = numpy.empty(shape, dtype)
    a.fill(numpy.nan)
    return a

然后

nans([3,4])

会输出

array([[ NaN,  NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN,  NaN]])

我在mailing list thread中找到了这段代码。

答案 4 :(得分:10)

如果您不立即回想起.empty.full方法,则可以随时使用乘法:

>>> np.nan * np.ones(shape=(3,2))
array([[ nan,  nan],
       [ nan,  nan],
       [ nan,  nan]])

当然它也适用于任何其他数值:

>>> 42 * np.ones(shape=(3,2))
array([[ 42,  42],
       [ 42,  42],
       [ 42, 42]])

但是@ u0b34a0f6ae的accepted answer快了3倍(CPU周期,而不是脑循环来记住numpy语法;):

$ python -mtimeit "import numpy as np; X = np.empty((100,100));" "X[:] = np.nan;"
100000 loops, best of 3: 8.9 usec per loop
(predict)laneh@predict:~/src/predict/predict/webapp$ master
$ python -mtimeit "import numpy as np; X = np.ones((100,100));" "X *= np.nan;"
10000 loops, best of 3: 24.9 usec per loop

答案 5 :(得分:4)

如上所述,numpy.empty()是要走的路。但是,对于对象,fill()可能不会完全按照您的想法执行:

In[36]: a = numpy.empty(5,dtype=object)
In[37]: a.fill([])
In[38]: a
Out[38]: array([[], [], [], [], []], dtype=object)
In[39]: a[0].append(4)
In[40]: a
Out[40]: array([[4], [4], [4], [4], [4]], dtype=object)

一种方法可以是例如:

In[41]: a = numpy.empty(5,dtype=object)
In[42]: a[:]= [ [] for x in range(5)]
In[43]: a[0].append(4)
In[44]: a
Out[44]: array([[4], [], [], [], []], dtype=object)

答案 6 :(得分:2)

此处尚未提及的另一种可能性是使用NumPy tile:

a = numpy.tile(numpy.nan, (3, 3))

同时给出

array([[ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN],
       [ NaN,  NaN,  NaN]])

我不知道速度比较。

答案 7 :(得分:1)

另一种选择是numpy.broadcast_to(val,n),无论大小如何,它都会在恒定时间内返回,并且也是最有效的内存使用方法(它返回重复元素的视图)。需要注意的是,返回值是只读的。

下面是使用与Nico Schlömer's answer中相同的基准所建议的所有其他方法的性能的比较。

enter image description here