首页 文章

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

提问于
浏览
129

我有以下代码:

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

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

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

谢谢

8 回答

  • 10

    你很少需要在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(..) 作为更快的选择 . OTOH,我喜欢numpy 's convenience implementation where you can assign values to whole slices at the time, the code'的意图非常明确 .

  • 25

    另一种选择是使用numpy.full,这是NumPy 1.8中提供的一个选项

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

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

  • 109

    我比较了建议的速度替代方案,并发现,对于足够大的矢量/矩阵来填充,除了 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)'
        )
    
  • 4

    你熟悉 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中找到了这段代码 .

  • 0

    如果您不立即回想起 .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
    
  • 30

    如上所述,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)
    
  • 1

    这里还没有提到的另一种可能性是使用NumPy磁贴:

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

    也给出了

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

    我不知道速度比较 .

  • 190

    另一个替代方案是 numpy.broadcast_to(val,n) ,无论大小如何都以恒定时间返回,并且也是最有效的内存(它返回重复元素的视图) . 需要注意的是返回的值是只读的 .

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

    enter image description here

相关问题