如何在NumPy中创建一个空数组/矩阵?


310

我无法弄清楚如何以通常使用列表的方式使用数组或矩阵。我想创建一个空数组(或矩阵),然后一次向其中添加一列(或行)。

目前,我能找到的唯一方法是:

mat = None
for col in columns:
    if mat is None:
        mat = col
    else:
        mat = hstack((mat, col))

而如果这是一个列表,我会做这样的事情:

list = []
for item in data:
    list.append(item)

有没有办法对NumPy数组或矩阵使用这种表示法?

Answers:


440

您对有效使用NumPy的思维模式有误。NumPy数组存储在连续的内存块中。如果要向现有阵列添加行或列,则需要将整个阵列复制到新的内存块中,从而为要存储的新元素创建间隙。如果反复进行以构建阵列,则效率非常低下。

在添加行的情况下,最好的选择是创建一个与数据集最终大小一样大的数组,然后逐行向其中添加数据:

>>> import numpy
>>> a = numpy.zeros(shape=(5,2))
>>> a
array([[ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])
>>> a[0] = [1,2]
>>> a[1] = [2,3]
>>> a
array([[ 1.,  2.],
   [ 2.,  3.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])

123
如果不需要将数组归零,则还有numpy.empty()。
janneb

21
使用empty()而不是zeros()有什么好处?
2012年

45
如果您要立即使用数据进行初始化,则可以节省将数据清零的费用。
marcorossi 2012年

16
@maracorossi .empty()意味着人们可以在单元格中找到随机值,但是创建数组的速度比使用.zeros()?更快。
user3085931 '16

6
@ user3085931是的!
弥敦道

98

NumPy数组是与列表非常不同的数据结构,旨在以不同的方式使用。您的使用hstack可能效率很低...每次调用它时,现有数组中的所有数据都将被复制到一个新数组中。(该append函数会有相同的问题。)如果您想一次建立一列矩阵,最好将其保留在列表中直到完成,然后再将其转换为数组。

例如


mylist = []
for item in data:
    mylist.append(item)
mat = numpy.array(mylist)

item可以是列表,数组或任何可迭代的,只要每个item元素具有相同数量的元素即可。
在这种特殊情况下(data保存矩阵列有些可迭代),您可以简单地使用


mat = numpy.array(data)

(还请注意,将其list用作变量名可能不是一个好习惯,因为它会用该名称掩盖内置类型,这可能会导致错误。)

编辑:

如果出于某种原因您确实想创建一个空数组,则可以使用 numpy.array([]),但这很少有用!


1
numpy数组/矩阵与Matlab数组/矩阵有根本区别吗?
levesque 2010年

1
如果由于某种原因需要定义一个空数组,但具有固定宽度(例如np.concatenate()),则可以使用:np.empty((0, some_width))。0,因此您的第一个数组不会成为垃圾。
NumesSanguis'9

56

要在NumPy中创建一个空的多维数组(例如,m*n用于存储矩阵的2D数组),以防万一您不知道m要追加多少行并且不在乎Stephen Simmons提到的计算成本(即重新构建数组),您可以将要附加到的尺寸压缩为0 X = np.empty(shape=[0, n])

例如,您可以使用这种方式(在这里m = 5我们假设在创建空矩阵时我们并不知道,以及n = 2):

import numpy as np

n = 2
X = np.empty(shape=[0, n])

for i in range(5):
    for j  in range(2):
        X = np.append(X, [[i, j]], axis=0)

print X

这将为您提供:

[[ 0.  0.]
 [ 0.  1.]
 [ 1.  0.]
 [ 1.  1.]
 [ 2.  0.]
 [ 2.  1.]
 [ 3.  0.]
 [ 3.  1.]
 [ 4.  0.]
 [ 4.  1.]]

1
这应该是OP提出的问题的答案,适用于您事先不知道#rows或想处理0行的用例的情况
Spcogg

26

我进行了很多研究,因为我需要在我的一个学校项目中使用numpy.array作为集合,并且需要将其初始化为空。在这里,我在Stack Overflow上没有找到任何相关的答案,所以我开始涂鸦的东西。

# Initialize your variable as an empty list first
In [32]: x=[]
# and now cast it as a numpy ndarray
In [33]: x=np.array(x)

结果将是:

In [34]: x
Out[34]: array([], dtype=float64)

因此,您可以按如下所示直接初始化np数组:

In [36]: x= np.array([], dtype=np.float64)

我希望这有帮助。


如问题所示,这不适用于数组,但对向量可能有用。
divenex

a=np.array([])似乎默认为float64
P i

7

您可以使用附加功能。对于行:

>>> from numpy import *
>>> a = array([10,20,30])
>>> append(a, [[1,2,3]], axis=0)
array([[10, 20, 30],      
       [1, 2, 3]])

对于列:

>>> append(a, [[15],[15]], axis=1)
array([[10, 20, 30, 15],      
       [1, 2, 3, 15]])

编辑
当然,正如其他答案中所述,除非每次对矩阵/数组进行一些处理(例如反转),否则每次将其添加到列表中时,我都会创建一个列表,将其添加到列表中,然后将其转换为数组。


3

如果您完全不知道数组的最终大小,则可以像这样增加数组的大小:

my_arr = numpy.zeros((0,5))
for i in range(3):
    my_arr=numpy.concatenate( ( my_arr, numpy.ones((1,5)) ) )
print(my_arr)

[[ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]]
  • 注意0第一行中的。
  • numpy.append是另一种选择。它调用numpy.concatenate

3

您可以将其应用于构建任何类型的数组,例如零:

a = range(5)
a = [i*0 for i in a]
print a 
[0, 0, 0, 0, 0]

4
如果您想用纯Python做到这一点,那a= [0] * 5是一个简单的解决方案
Makers_F 2015年

3

这是一些使numpys看起来更像列表的解决方法

np_arr = np.array([])
np_arr = np.append(np_arr , 2)
np_arr = np.append(np_arr , 24)
print(np_arr)

输出:array([2.,24.])


2

根据您使用它的目的,您可能需要指定数据类型(请参见'dtype')。

例如,要创建一个8位值的2D数组(适合用作单色图像):

myarray = numpy.empty(shape=(H,W),dtype='u1')

对于RGB图像,在形状中包括颜色通道的数量: shape=(H,W,3)

您可能还想考虑使用零初始化,numpy.zeros而不是使用numpy.empty。请参阅此处的注释。


1

我认为您想处理列表的大部分工作,然后将结果用作矩阵。也许这是一种方式;

ur_list = []
for col in columns:
    ur_list.append(list(col))

mat = np.matrix(ur_list)

1

我认为您可以创建空的numpy数组,例如:

>>> import numpy as np
>>> empty_array= np.zeros(0)
>>> empty_array
array([], dtype=float64)
>>> empty_array.shape
(0,)

当您要在循环中附加numpy数组时,此格式很有用。


0

为了创建一个空的NumPy数组而不定义其形状,有一种方法:

1。

arr = np.array([]) 

首选。因为您知道您将以numpy的形式使用它。

2。

arr = []
# and use it as numpy. append to it or etc..

NumPy之后将其转换为np.ndarray类型,无需额外的操作[] dimionsion

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.