如何将一个数组重复m次

3
我有一个数组,例如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
@hgs3,如果我多次打印同一个数组,输出会是一样的吗? - Katenn
3个回答

5

在numpy中有许多选项:

  1. The simplest is np.stack, with the new axis set to 0:

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

    This is a generalization of np.vstack, which can accept a variable m in the same way:

    result = np.vstack((arr,) * m)
    
  2. Since you are looking to expand the first dimension and not the second, you can use np.tile:

    result = np.tile(arr, [m, 1])
    
  3. For this simple case, you can repeat the elements individually for the same result using np.repeat. This is a bit hacky, but it works just as well:

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

    If arr is already a numpy array, you can add the leading dimension more explicitly:

    result = np.repeat(arr[None, :], m, axis=0)
    
  4. A slightly more convoluted method, but which showcases what is going on under the hood better is using np.concatenate:

    np.concatenate(([arr],) * m, axis=0)
    
  5. In the same spirit as concatenate, you can use the constructor np.array directly:

    np.array([arr] * m)
    
  6. An ugly method is to use muliplication (combined with broadcasting):

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

    Setting the dtype to a very small integer type pretty much ensures that the result will be promoted to the actual type of your array.

  7. The previous methods copy the array multiple times to get the 2D data. But since the data is repeated, you don't actually need to copy it. Instead, you can make a view that creates a fake first dimension using broadcasting. Specifically, the np.broadcast_to function will do exactly what you want:

     result = np.broadcast_to(arr, [m, len(arr)])
    
  8. There is a more general approach even than the previous to making views is np.lib.stride_tricks.as_strided.

    First, let's reiterate the warning from the documentation:

    Warning

    This function has to be used with extreme care, see notes.

    Unless you know the byte-size of the dtype you plan on using ahead of time, it's a good idea to ensure that arr is a numpy array to get the strides from it:

    arr = np.asanyarray(arr)
    result = np.lib.stride_tricks.as_strided(arr, shape=(m, arr.size), strides=(0,) + arr.strides)
    
在最后两种情况下,如果您想将视图扩展为包含每个元素的适当副本的完整缓冲区,则可以复制数据:copy
result = result.copy()

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


1

您可以使用:

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广播 ,而不需要重复你的数组。

谢谢!那个有效。 - Katenn
@Katenn如果这个回答解决了你的问题,请在它左边的方框中打勾标记为答案! - ti7

0

你可以做:

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

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


2
这实际上是一个常见的陷阱!list对象是按引用传递的,因此列表是指针的集合;尝试更改一个array[1][2] = 10[[1, 2, 10, 4], [1, 2, 10, 4], [1, 2, 10, 4]]@Quang Hoang的答案可以解决这个问题,因为它不是一个列表,而是一个numpy.array - ti7
啊,好的,谢谢你的回复!你说得完全正确。 - Schwarztrinker
@Schwarztrinker。你也可以使用numpy的步幅魔法来模拟列表行为,就像我在答案中展示的最后两种方法一样。 - Mad Physicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接