【问题标题】:initialize a numpy array初始化一个numpy数组
【发布时间】:2011-05-30 22:33:35
【问题描述】:

有没有办法初始化一个形状的 numpy 数组并添加到它?我将通过一个列表示例来解释我需要什么。如果我想创建一个循环生成的对象列表,我可以这样做:

a = []
for i in range(5):
    a.append(i)

我想用一个 numpy 数组做类似的事情。我知道 vstack、concatenate 等。但是,似乎这些需要两个 numpy 数组作为输入。我需要的是:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

big_array 的形状应为 (10,4)。如何做到这一点?


编辑:

我想添加以下说明。我知道我可以定义 big_array = numpy.zeros((10,4)) 然后填写它。但是,这需要提前指定 big_array 的大小。我知道在这种情况下的大小,但如果我不知道怎么办?当我们在python中使用.append函数扩展列表时,我们不需要提前知道它的最终大小。我想知道是否存在类似的东西可以从较小的数组创建一个更大的数组,从一个空数组开始。

【问题讨论】:

  • 顺便说一下,您的第一个代码示例可以作为列表理解简洁而简洁地编写:[i for i in range(5)]。 (等同于:list(range(5)),虽然这是一个人为的例子。)
  • 哪种解决方案适合您?我正在尝试做类似x = numpy.array() 之类的事情,就像我们对y = [] 之类的列表所做的那样;但它没有用

标签: python arrays numpy


【解决方案1】:

numpy.zeros

返回给定形状的新数组和 类型,用零填充。

numpy.ones

返回给定形状的新数组和 类型,用一个填充。

numpy.empty

返回给定形状的新数组和 类型,不初始化条目。


但是,我们通过将元素附加到列表来构造数组的思路在 numpy 中使用不多,因为它的效率较低(numpy 数据类型更接近底层 C 数组)。相反,您应该将数组预先分配到您需要的大小,然后填充行。不过,如果必须,您可以使用numpy.append

【讨论】:

  • 我知道我可以设置 big_array = numpy.zeros 然后用创建的小数组填充它。但是,这需要我提前指定 big_array 的大小。有没有像列表函数的 .append 那样我没有提前指定大小的地方。谢谢!
  • @Curious2learn。不,在 Numpy 中没有什么能比得上 append。有一些函数可以通过创建新数组来连接数组或堆叠它们,但它们不是通过追加来实现的。这是因为数据结构的设置方式。 Numpy 数组由于能够更紧凑地存储值而变得快速,但它们需要具有固定大小才能获得这种速度。 Python 列表旨在以速度和大小为代价更加灵活。
  • @Curious:嗯,在 numpy 中有一个 append。只是不预分配效率较低(在这种情况下,效率要低得多,因为appending 每次都会复制整个数组),所以它不是标准技术。
  • 如果np.empty 数组中只有一部分被值填充了怎么办?剩下的“空”物品呢?
  • 如果您只知道宽度(例如np.concatenate() 所需的宽度),您可以使用:np.empty((0, some_width)) 进行初始化。 0,所以你的第一个数组不会是垃圾。
【解决方案2】:

我通常这样做的方法是创建一个常规列表,然后将我的东西附加到其中,最后将列表转换为一个 numpy 数组,如下所示:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

当然,您的最终对象在创建步骤中占用了两倍的内存空间,但是添加到 python 列表非常快,并且还可以使用 np.array() 创建。

【讨论】:

  • 如果你提前知道数组的大小,这不是要走的路,但是......我最终经常使用这种方法,而我不知道知道阵列最终会有多大。例如,从文件或其他进程读取数据时。它并不像一开始看起来那么糟糕,因为 python 和 numpy 非常聪明。
【解决方案3】:

在 numpy 1.8 中引入:

numpy.full

返回一个给定形状和类型的新数组,用 fill_value 填充。

例子:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])

【讨论】:

    【解决方案4】:

    python 的数组模拟

    a = []
    for i in range(5):
        a.append(i)
    

    是:

    import numpy as np
    
    a = np.empty((0))
    for i in range(5):
        a = np.append(a, i)
    

    【讨论】:

    • @NicholasTJ:empty((0)) 初始化一个 numpy 数组。
    • np.empty((0)) 中的括号是多余的。
    【解决方案5】:

    使用特定矩阵初始化 numpy 数组:

    import numpy as np
    
    mat = np.array([[1, 1, 0, 0, 0],
                    [0, 1, 0, 0, 1],
                    [1, 0, 0, 1, 1],
                    [0, 0, 0, 0, 0],
                    [1, 0, 1, 0, 1]])
    
    print mat.shape
    print mat
    

    输出:

    (5, 5)
    [[1 1 0 0 0]
     [0 1 0 0 1]
     [1 0 0 1 1]
     [0 0 0 0 0]
     [1 0 1 0 1]]
    

    【讨论】:

      【解决方案6】:

      numpy.fromiter() 就是你要找的东西:

      big_array = numpy.fromiter(xrange(5), dtype="int")
      

      它也适用于生成器表达式,例如:

      big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )
      

      如果您事先知道数组的长度,则可以使用可选的 'count' 参数指定它。

      【讨论】:

      • 我实际上运行了 timeit,我认为 np.fromiter() 可能比 np.array() 慢。 timeit("np.array(i for i in xrange(100))", setup="import numpy as np", number = 10000) -> 0.02539992332458496, vs timeit("np.fromiter((i for i in xrange( 100)), dtype=int)", setup="import numpy as np", number = 10000) -> 0.13351011276245117
      【解决方案7】:

      在进行数组计算时,您确实希望尽可能避免显式循环,因为这会降低这种计算形式的速度增益。有多种方法可以初始化一个 numpy 数组。如果你想让它充满零,按照 katrielalex 说的做:

      big_array = numpy.zeros((10,4))

      编辑:你正在制作什么样的序列?您应该查看创建数组的不同 numpy 函数,例如 numpy.linspace(start, stop, size)(等间距数字)或 numpy.arange(start, stop, inc)。在可能的情况下,这些函数将使数组比在显式循环中执行相同的工作快得多

      【讨论】:

        【解决方案8】:

        对于您的第一个数组示例使用,

        a = numpy.arange(5)
        

        要初始化 big_array,请使用

        big_array = numpy.zeros((10,4))
        

        这假设你想用零初始化,这很典型,但还有很多其他的ways to initialize an array in numpy

        编辑: 如果您事先不知道 big_array 的大小,通常最好先使用 append 构建一个 Python 列表,当您将所有内容收集到列表中时,使用 numpy.array(mylist) 将此列表转换为 numpy 数组。这样做的原因是列表意味着非常有效和快速地增长,而 numpy.concatenate 将非常低效,因为 numpy 数组不容易改变大小。但是一旦所有东西都收集在一个列表中,并且你知道最终的数组大小,就可以有效地构造一个 numpy 数组。

        【讨论】:

          【解决方案9】:

          我意识到这有点晚了,但我没有注意到任何其他提到索引到空数组的答案:

          big_array = numpy.empty(10, 4)
          for i in range(5):
              array_i = numpy.random.random(2, 4)
              big_array[2 * i:2 * (i + 1), :] = array_i
          

          这样,您可以使用numpy.empty 预分配整个结果数组,并使用索引分配随时填写行。

          在您给出的示例中使用empty 而不是zeros 进行预分配是完全安全的,因为您保证整个数组将被您生成的块填充。

          【讨论】:

            【解决方案10】:

            我建议先定义形状。 然后对其进行迭代以插入值。

            big_array= np.zeros(shape = ( 6, 2 ))
            for it in range(6):
                big_array[it] = (it,it) # For example
            
            >>>big_array
            
            array([[ 0.,  0.],
                   [ 1.,  1.],
                   [ 2.,  2.],
                   [ 3.,  3.],
                   [ 4.,  4.],
                   [ 5.,  5.]])
            

            【讨论】:

              【解决方案11】:

              当您处于以下情况时:

              a = []
              for i in range(5):
                  a.append(i)
              

              并且您想要在 numpy 中使用类似的东西,以前的几个答案已经指出了这样做的方法,但是正如 @katrielalex 指出的那样,这些方法效率不高。执行此操作的有效方法是构建一个长列表,然后在您拥有一个长列表后按照您想要的方式重新调整它。例如,假设我正在从文件中读取一些行,并且每一行都有一个数字列表,并且我想构建一个形状的 numpy 数组(读取的行数,每行中向量的长度)。以下是我将如何更有效地做到这一点:

              long_list = []
              counter = 0
              with open('filename', 'r') as f:
                  for row in f:
                      row_list = row.split()
                      long_list.extend(row_list)
                      counter++
              #  now we have a long list and we are ready to reshape
              result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array
              

              【讨论】:

                【解决方案12】:

                也许这样的东西会满足你的需求..

                import numpy as np
                
                N = 5
                res = []
                
                for i in range(N):
                    res.append(np.cumsum(np.ones(shape=(2,4))))
                
                res = np.array(res).reshape((10, 4))
                print(res)
                

                产生以下输出

                [[ 1.  2.  3.  4.]
                 [ 5.  6.  7.  8.]
                 [ 1.  2.  3.  4.]
                 [ 5.  6.  7.  8.]
                 [ 1.  2.  3.  4.]
                 [ 5.  6.  7.  8.]
                 [ 1.  2.  3.  4.]
                 [ 5.  6.  7.  8.]
                 [ 1.  2.  3.  4.]
                 [ 5.  6.  7.  8.]]
                

                【讨论】:

                  【解决方案13】:

                  如果你想在多维数组中添加你的项目,这里是解决方案。

                  import numpy as np
                  big_array = np.ndarray(shape=(0, 2, 4) # Empty with height and width 2, 4 and length 0
                  
                  for i in range(5):
                      big_array = np.concatenate((big_array, i))
                  

                  这里是 numpy official document for referral

                  【讨论】:

                    猜你喜欢
                    • 2014-06-28
                    • 1970-01-01
                    • 2018-12-04
                    • 2020-10-25
                    • 2020-12-05
                    • 2015-08-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-12-25
                    相关资源
                    最近更新 更多