代码之家  ›  专栏  ›  技术社区  ›  Karnivaurus

是否存在作用于现有数组的“np.repeat”?

  •  2
  • Karnivaurus  · 技术社区  · 5 年前

    我有一个很大的numpy数组,我想在循环的每次迭代中用新数据填充它。数组中填充了沿轴0重复的数据,例如:

    [[1, 5],
     [1, 5],
     [1, 5],
     [1, 5]]
    

    我知道如何在每次迭代中从头开始创建这个数组:

    x = np.repeat([[1, 5]], 4, axis=0)
    

    但是,我不想每次都创建一个新的数组,因为它是一个非常大的数组(比4x2大得多)。相反,我想使用上面的代码提前创建数组,然后在每次迭代时用新数据填充数组。

    但是 np.repeat() 返回新数组,而不是对现有数组执行操作。有等价物吗 NP.重复() 用于填充现有数组?

    1 回复  |  直到 5 年前
        1
  •  5
  •   Andras Deak -- Слава Україні    5 年前

    正如我们在评论中所指出的,您可以使用广播分配来用合适大小的一维数组填充二维数组:

    x[...] = [1, 5]
    

    如果您的大数组在每一行中总是包含相同的项(也就是说,以后不会更改这些预设值),那么您几乎可以肯定地在代码的后面部分使用广播,并且只使用初始值 x

    x = np.array([[1, 5]])
    

    此数组具有形状 (1, 2) 与其他形状阵列兼容的广播 (4, 2) 在上面的示例中可能有。

    如果每行中始终需要相同的值 由于某些原因,您不能使用广播(这两种情况都极不可能),您可以使用 broadcast_to 要使用显式二维形状创建数组而不复制内存,请执行以下操作:

    x_bc = np.broadcast_to([1, 5], (4, 2)) # broadcast 1d [1, 5] to shape (4, 2)
    

    这可能有效,因为它的形状正确,内存中只有两个唯一的元素:

    >>> x_bc
    array([[1, 5],
           [1, 5],
           [1, 5],
           [1, 5]])
    
    >>> x_bc.strides
    (0, 8)
    

    但是您不能改变它,因为它是只读视图:

    >>> x_bc[0, :] = [2, 4]
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-35-ae12ecfe3c5e> in <module>
    ----> 1 x_bc[0, :] = [2, 4]
    
    ValueError: assignment destination is read-only
    

    所以,如果每行中只需要相同的值 你不能用广播 你想稍后改变这些相同的行,你可以使用 stride tricks 要将相同的一维数据映射到二维数组,请执行以下操作:

    >>> x_in = np.array([1, 5])
    ... x_strided = np.lib.stride_tricks.as_strided(x_in, shape=(4,) + x_in.shape,
    ...                                             strides=(0,) + x_in.strides[-1:])
    
    >>> x_strided
    array([[1, 5],
           [1, 5],
           [1, 5],
           [1, 5]])
    
    >>> x_strided[0, :] = [2, 4]
    
    >>> x_strided
    array([[2, 4],
           [2, 4],
           [2, 4],
           [2, 4]])
    

    它为您提供了一个固定形状的二维数组,该数组始终包含一个唯一的行,并且改变任何一行会改变其余的行(因为基础数据只对应一行)。小心处理,因为如果你想有两个不同的排,你必须做其他的事情。