如何将一个数组重复m次

Kat*_*enn 3 numpy array-broadcasting

我有一个数组,例如arr = [1, 2, 3, 4]、 和m = 3。我想制作一个包含m行的矩阵,重复该数组。该示例的输出将是

[[1, 2, 3, 4],
 [1, 2, 3, 4],
 [1, 2, 3, 4]]
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?我尝试过

np.vstack((arr, arr, arr))
Run Code Online (Sandbox Code Playgroud)

然而,据我了解,这只有在我有效地硬核时才有效m

Mad*_*ist 5

numpy 中有很多选项:

  1. 最简单的是np.stack,将新轴设置为 0:

    result = np.stack((arr,) * m, axis=0)
    
    Run Code Online (Sandbox Code Playgroud)

    这是 的概括,它可以以相同的方式np.vstack接受变量:m

    result = np.vstack((arr,) * m)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 由于您希望扩展第一个维度而不是第二个维度,因此您可以使用np.tile

    result = np.tile(arr, [m, 1])
    
    Run Code Online (Sandbox Code Playgroud)
  3. 对于这个简单的情况,您可以使用 单独重复元素以获得相同的结果np.repeat。这有点 hacky,但效果也很好:

    result = np.repeat([arr], m, axis=0)
    
    Run Code Online (Sandbox Code Playgroud)

    如果arr已经是一个 numpy 数组,您可以更明确地添加前导维度:

    result = np.repeat(arr[None, :], m, axis=0)
    
    Run Code Online (Sandbox Code Playgroud)
  4. 一种稍微复杂一些的方法,但可以更好地展示幕后发生的事情,那就是使用np.concatenate

    np.concatenate(([arr],) * m, axis=0)
    
    Run Code Online (Sandbox Code Playgroud)
  5. 与 一样,您可以直接concatenate使用构造函数:np.array

    np.array([arr] * m)
    
    Run Code Online (Sandbox Code Playgroud)
  6. 一个丑陋的方法是使用乘法(与广播结合):

    result = arr * np.ones((m, 1), dtype=np.int8)
    
    Run Code Online (Sandbox Code Playgroud)

    将 dtype 设置为非常小的整数类型几乎可以确保结果将提升为数组的实际类型。

  7. 前面的方法多次复制数组来获取二维数据。但由于数据是重复的,因此您实际上不需要复制它。相反,您可以创建一个使用广播创建假第一维度的视图。具体来说,该np.broadcast_to函数将完全按照您的要求执行:

     result = np.broadcast_to(arr, [m, len(arr)])
    
    Run Code Online (Sandbox Code Playgroud)
  8. 有一种比以前更通用的发表意见的方法np.lib.stride_tricks.as_strided

    首先,让我们重申一下文档中的警告:

    警告

    使用此功能必须非常小心,请参阅注释。

    除非您提前知道计划使用的数据类型的字节大小,否则最好确保它arr是一个 numpy 数组以从中获取步幅:

    arr = np.asanyarray(arr)
    result = np.lib.stride_tricks.as_strided(arr, shape=(m, arr.size), strides=(0,) + arr.strides)
    
    Run Code Online (Sandbox Code Playgroud)

在最后两种情况下,如果要将视图扩展到包含每个元素的正确副本的完整缓冲区,则可以复制数据:

result = result.copy()
Run Code Online (Sandbox Code Playgroud)

如果不进行扩展,您将有效地模拟对同一列表的多个引用的行为,其中修改任何元素都会更改同一列中的所有元素。