【问题标题】:How to append numpy.array to other numpy.array?如何将 numpy.array 附加到其他 numpy.array?
【发布时间】:2015-05-08 11:15:20
【问题描述】:

我想创建 2D numpy.array 一开始只知道它的形状,即 shape=2。现在,我想在for循环中创建ith一维numpy.arrays,并将它们添加到shape=2的主矩阵中,所以我会得到这样的东西:

matrix=
[numpy.array 1]
[numpy.array 2]
...
[numpy.array n]

我怎样才能做到这一点?我尝试使用:

matrix = np.empty(shape=2)
for i in np.arange(100):
    array = np.zeros(random_value)
    matrix = np.append(matrix, array)

但是由于print(np.shape(matrix)),在循环之后,我得到类似:

(some_number, )

如何将每个新的array 附加到matrix 的下一行?提前谢谢你。

【问题讨论】:

  • 这是一种非常低效的创建数组的方法。每次附加到数组时,它都会生成一个新副本。如果您在循环中进行追加,则随着数组大小的增长,此过程会变得越来越慢。预先分配输出数组然后按原样填充行要好得多。如果您不知道输出的确切大小,那么您最初可以分配一个比您认为需要的更大的数组,并在完成后仅索引您需要的行。另一种选择是创建一个数组列表,然后在列表中调用np.array()np.vstack()
  • 此外,您似乎正在尝试创建一个参差不齐的数组(即每行长度不同的数组),而 numpy 实际上仅设计用于处理矩形数组。例如,考虑索引如何为不规则数组工作 - 没有直接的方法可以在不规则维度上进行切片索引,例如a[:, :10]。根据您要使用输出的目的,使用数组列表或创建一个用 NaN 填充缺失值的矩形数组可能更有意义。

标签: python arrays numpy


【解决方案1】:

我建议使用列表

matrix = []

for i in range(10):
    a = np.ones(2)
    matrix.append(a)

matrix = np.array(matrix)

list 没有每次使用 append 时都被复制到内存中的缺点。所以你避免了 ali_m 描述的问题。在操作结束时,您只需将列表对象转换为 numpy 数组。

【讨论】:

    【解决方案2】:

    我怀疑你问题的根源是np.empty(shape=2)中“形状”的含义

    如果我运行您的代码的小版本

    matrix = np.empty(shape=2)
    for i in np.arange(3):
        array = np.zeros(3)
        matrix = np.append(matrix, array)
    

    我明白了

    array([  9.57895902e-259,   1.51798693e-314,   0.00000000e+000,
         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000,   0.00000000e+000])
    

    看到开头那两个奇数了吗?这些是由np.empty(shape=2) 制作的。 matrix(2,) 形状的数组开始,而不是空的二维数组。 append 只是在其中添加了 3 个零的集合,从而产生了一个 (11,) 数组。

    现在,如果您从具有正确列数的 2 数组开始,并在第 1 维上进行连接,您将得到一个多行数组。 (行仅在 2d 或更大范围内有意义)。

    mat=np.zeros((1,3))
    for i in range(1,3):
        mat = np.concatenate([mat, np.ones((1,3))*i],axis=0)
    

    产生:

    array([[ 0.,  0.,  0.],
           [ 1.,  1.,  1.],
           [ 2.,  2.,  2.]])
    

    进行这样的迭代构造的更好方法是使用列表追加

    alist = []
    for i in range(0,3):
        alist.append(np.ones((1,3))*i)
    mat=np.vstack(alist)
    

    alist 是:

    [array([[ 0.,  0.,  0.]]), array([[ 1.,  1.,  1.]]), array([[ 2.,  2.,  2.]])]
    

    mat

    array([[ 0.,  0.,  0.],
           [ 1.,  1.,  1.],
           [ 2.,  2.,  2.]])
    

    使用vstack,您可以使用np.ones((3,),因为它将所有输入转换为二维数组。

    append 可以工作,但它还需要axis=0 参数和 2 个数组。它被滥用,通常被错误地类比为列表附加。它只是concatenate 的另一个前端。所以我宁愿不使用它。

    请注意,其他发帖人假设您的random value 在迭代期间发生了更改。这将产生不同长度的数组。对于一维追加,它仍然会产生长的一维数组。但是二维追加是行不通的,因为二维数组不能乱七八糟。

    mat = np.zeros((2,),int)
    for i in range(4):
        mat=np.append(mat,np.ones((i,),int)*i)
    # array([0, 0, 1, 2, 2, 3, 3, 3])
    

    【讨论】:

      【解决方案3】:

      你要找的函数是np.vstack

      这是您的示例的修改版本

      import numpy as np
      
      matrix = np.empty(shape=2)
      
      for i in np.arange(3):
          array = np.zeros(2)
          matrix = np.vstack((matrix, array))
      

      结果是

      array([[ 0.,  0.],
             [ 0.,  0.],
             [ 0.,  0.],
             [ 0.,  0.]])
      

      【讨论】:

      • np.vstack函数要求堆叠数组的维数相同。
      • 如果你真的想这样做,你可以创建一个存储列表引用的 numpy 数组,但它并不是那么高效(见这里stackoverflow.com/questions/3386259/…)。
      • 那你为什么要外部数组是一个 numpy 数组呢?
      • 在循环中创建数组列表会快得多,然后在列表上调用一次np.vstack。这是因为连接数组会生成副本,而将数组附加到列表则不会。
      • 我完全同意。我会更新示例以反映这一点,但是我不知道 OP 试图实现什么,因为他说他想有效地 vstack 不同长度的数组。
      猜你喜欢
      • 2023-03-21
      • 2017-08-24
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多