【问题标题】:How can I repeat an array m times [duplicate]我怎样才能重复一个数组m次[重复]
【发布时间】:2021-01-28 20:42:48
【问题描述】:

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

[[1, 2, 3, 4],
 [1, 2, 3, 4],
 [1, 2, 3, 4]]

我该怎么做?我试过了

np.vstack((arr, arr, arr))

但是,据我了解,这只有在我有效地坚持 m 时才有效。

【问题讨论】:

  • 你问题的最后一句话让我失望。在那之前,听起来您只是想打印相同的数组 M 次。堆栈是干什么用的?
  • @hgs3,如果我多次打印同一个数组,输出是否相同?

标签: numpy array-broadcasting


【解决方案1】:

numpy 中有很多选项:

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

    result = np.stack((arr,) * m, axis=0)
    

    这是np.vstack的泛化,同样可以接受一个变量m:

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

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

    result = np.repeat([arr], m, axis=0)
    

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

    result = np.repeat(arr[None, :], m, axis=0)
    
  4. 使用np.concatenate:

    np.concatenate(([arr],) * m, axis=0)
    
  5. 本着与concatenate相同的精神,可以直接使用构造函数np.array:

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

    result = arr * np.ones((m, 1), dtype=np.int8)
    

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

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

     result = np.broadcast_to(arr, [m, len(arr)])
    
  8. 还有一种比以前更通用的方法来制作视图是np.lib.stride_tricks.as_strided。

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

    警告

    使用此功能时必须格外小心,请参阅注释。

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

    arr = np.asanyarray(arr)
    result = np.lib.stride_tricks.as_strided(arr, shape=(m, arr.size), strides=(0,) + arr.strides)
    

在最后两种情况下,如果你想将视图扩展为一个完整的缓冲区,其中包含每个元素的正确副本,你可以copy数据:

result = result.copy()

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

【讨论】:

    【解决方案2】:

    你可以使用:

    import numpy as np
    arr, m = [1,2,3,4], 3
    
    np.vstack([arr]*m)
    

    输出:

    array([[1, 2, 3, 4],
           [1, 2, 3, 4],
           [1, 2, 3, 4]])
    

    另一方面,为什么需要创建这样的矩阵?您可能正在寻找 numpy broadcasting 而无需重复您的数组。

    【讨论】:

    • 谢谢!有效
    • @Katenn 如果这回答了您的问题,请将其标记为答案并在其左侧打勾!
    【解决方案3】:

    你可以这样做:

    n = [1,2,3,4]
    m = 3
    
    i = 0; 
    array = []
    
    while(i<m):
        array.append(n)
        i+=1
    
    print(array)
    

    => [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]

    【讨论】:

    • 这其实是一个常见的陷阱! list 对象是按引用的,因此列表是指针的集合;尝试改变一个array[1][2] = 10:[[1, 2, 10, 4], [1, 2, 10, 4], [1, 2, 10, 4]] @Quang Hoang 的答案解决了这个问题,因为它不是一个列表,而是一个numpy.array
    • 好的,谢谢你的回复!你说得对
    • @Schwarztrinker。您也可以使用 numpy stride 魔术来模拟列表行为,就像我在答案中展示的最后两种方法一样
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 2018-11-25
    • 2015-09-13
    • 1970-01-01
    相关资源
    最近更新 更多