初始化一个numpy数组


129

有没有办法初始化形状的numpy数组并将其添加到其中?我将通过列表示例来说明我需要的内容。如果要创建循环中生成的对象列表,可以执行以下操作:

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

我想对一个numpy数组做类似的事情。我了解vstack,串联等。但是,这些似乎需要两个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的大小。我知道这种情况下的大小,但是如果我不知道该怎么办?当我们使用该.append函数在python中扩展列表时,我们不需要事先知道其最终大小。我想知道是否存在从空数组开始的从较小数组创建较大数组的类似方法。


顺便提一下,您的第一个代码示例可以简洁明了地编写为列表理解:[i for i in range(5)]。(等效地:list(range(5)),尽管这是一个人为的例子。)
Katriel 2010年

哪种解决方案对您有用?我正在尝试做类似的事情,就像x = numpy.array()我们对一个清单这样做y = []; 但这
没用

Answers:


160

numpy.zeros

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

要么

numpy.ones

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

要么

numpy.empty

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


但是,通过将元素追加到列表来构造数组的思路在numpy中使用不多,因为它效率较低(numpy数据类型更接近基础C数组)。相反,您应该将数组预分配为所需的大小,然后填写行。不过,您可以numpy.append根据需要使用。


2
我知道我可以设置big_array = numpy.zeros,然后用创建的小数组填充它。但是,这需要我预先指定big_array的大小。有没有像.append那样的list函数,我没有事先指定大小。谢谢!
Curious2learn 2010年

2
@ Curious2learn。不,没有什么比Numpy中的append更像。有一些函数可以通过创建新数组来连接或堆叠数组,但不能通过追加来实现。这是因为数据结构的设置方式。Numpy数组由于能够更紧凑地存储值而变得很快,但是它们必须具有固定的大小才能获得此速度。Python列表旨在以速度和大小为代价变得更加灵活。
贾斯汀·皮

3
@好奇:好吧,有一个appendnumpy。只是不进行预分配效率较低(在这种情况下,效率较低,因为appending每次都会复制整个数组),所以这不是标准技术。
卡特里尔(Katriel)2010年

1
如果仅np.empty数组的一部分被值填充怎么办?剩下的“空”物品又如何呢?
李李

1
如果您只知道宽度(例如所需np.concatenate()),则可以使用进行初始化np.empty((0, some_width))。0,因此您的第一个数组不会成为垃圾。
NumesSanguis

40

我通常这样做的方法是创建一个常规列表,然后将其添加到列表中,最后将列表转换为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()进行创建也是如此。


11
如果您提前知道数组的大小,这不是可行的方法,但是...当我不知道数组最终会变成多大时,我经常使用此方法。例如,从文件或其他进程读取数据时。由于python和numpy非常聪明,所以它并不像乍看起来那样可怕。
travc

18

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

13

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)

5
@NicholasTJ:empty((0))初始化一个numpy数组。
Adobe

2
np.empty((0))中的括号是多余的。
Szymon Roziewski '18

7

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'参数指定它的长度。


2
我实际上运行了timeit,我认为np.fromiter()可能比np.array()慢。timeit(“ np.array(i for xrange(100)中的i,i中的i用于xrange(100))”),setup =“ import numpy as np”,number = 10000)-> 0.02539992332458496,与timeit(“ np.fromiter((i for i in xrange( 100)),dtype = int)“,setup =”将numpy导入为np“,数字= 10000)-> 0.13351011276245117
hlin117 2014年

6

您确实希望在进行数组计算时尽可能避免显式循环,因为这会降低这种形式的计算的速度增益。有多种初始化numpy数组的方法。如果要用零填充,请按照katrielalex的指示进行:

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

编辑:您正在制作哪种顺序?您应该查看创建数组的不同numpy函数,例如numpy.linspace(start, stop, size)(等号)或numpy.arange(start, stop, inc)。在可能的情况下,这些函数将使数组比在显式循环中完成相同工作的速度快得多


5

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

a = numpy.arange(5)

要初始化big_array,请使用

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

假设您要用零初始化,这很典型,但是还有许多其他方法可以在numpy中初始化数组

编辑: 如果您事先不知道big_array的大小,通常最好首先使用append构建一个Python列表,并且当列表中收集了所有内容时,请使用将该列表转换为numpy数组numpy.array(mylist)。原因是列表的目的是非常高效和快速地增长,而numpy.concatenate效率很低,因为numpy数组不容易更改大小。但是,一旦所有内容都收集到列表中,并且您知道最终的数组大小,就可以有效地构造一个numpy数组。


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

3

每当您处于以下情况时:

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

2

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

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您给出的示例是完全安全的,因为您可以保证整个数组将被生成的块填充。


2

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

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

1

也许这样的东西会满足您的需求。

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.]]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.