Arrays Python:附加到numpy数组

Arrays Python:附加到numpy数组,arrays,python-2.7,numpy,Arrays,Python 2.7,Numpy,在某些情况下,希望连接的numpy数组覆盖原始numpy数组。 我想讨论一个复杂结构数组中的numpy数组示例。 这个问题是通过回答一个关于结构化数组的问题而产生的 类似问题 有几种方法,如numpy.append,numpy.concatenate,numpy.vstack或numpy.hstack 它们中的每一个都会创建一个新数组,不能通过返回如下错误消息将该数组分配回旧变量: ValueError: could not broadcast input array from sha

在某些情况下,希望连接的numpy数组覆盖原始numpy数组。 我想讨论一个复杂结构数组中的numpy数组示例。 这个问题是通过回答一个关于结构化数组的问题而产生的

类似问题 有几种方法,如
numpy.append
numpy.concatenate
numpy.vstack
numpy.hstack

它们中的每一个都会创建一个新数组,不能通过返回如下错误消息将该数组分配回旧变量:

ValueError: could not broadcast input array from shape (1,2,3) into shape (1,2,2)
可能的方法 作为一个简单但耗时的解决方案,我可以定义一个新的空numpy数组,用旧数据和应该追加的数据填充该数组


还感谢您提供其他解决方案。

A
numpy
数组将其数据保存在固定大小的缓冲区中。诸如
shape
strips
dtype
等属性用于解释该数据。这些属性可以更改,数据缓冲区中的值也可以更改。但是任何改变缓冲区大小的操作都需要一个副本

追加
连接
等都会创建一个新数组,并用原始数组中的数据填充它

您的
append
操作将创建一个新的
(1,2,3)
数组。它不能替换
x
缓冲区中的
(1,2,2)
字节字符串

如果将
('Table',float64,(2,2))
替换为
('Table',object)
,则可以更改
x['Table']
。这是因为
x
现在包含一个指向单独数组的指针。赋值将一个指针替换为另一个指针,而不更改
x
缓冲区的大小。这就像更改字典的值,或者替换列表中的嵌套列表

为什么要尝试使用结构化数组而不是传统的Python结构,如
list
dict
或自定义类对象

下面是一个有效的序列:

In [116]: x = np.zeros(1, dtype = [('Table', 'O'),
                         ('Number', np.float),
                         ('String', '|S10')])

In [117]: x['Table'][0] = np.zeros((2,2),dtype=np.float64)

In [118]: x['Table'][0] = np.append(x['Table'][0], np.array([[[1], [2]]]))

In [119]: x
Out[119]: 
array([([0.0, 0.0, 0.0, 0.0, 1.0, 2.0], 0.0, '')], 
      dtype=[('Table', 'O'), ('Number', '<f8'), ('String', 'S10')])
x['Table']
是另一个结构化数组

回顾原始的
x
定义,让我们给它3行(元素):

但无论如何,我都无法扩展它,除非创建一个新的
x
数组


另一种类似于构造的结构是字典:

In [156]: x={'Table': np.zeros((1,2,2),dtype=np.float64),
             'Number':np.zeros((1,)), 
             'String':['']}

In [157]: x
Out[157]: 
{'Number': array([ 0.]),
 'String': [''],
 'Table': array([[[ 0.,  0.],
        [ 0.,  0.]]])}

In [158]: x['Table'] =np.append(x['Table'],[1,2])

In [159]: x
Out[159]: 
{'Number': array([ 0.]),
 'String': [''],
 'Table': array([ 0.,  0.,  0.,  0.,  1.,  2.])}

从CSV文件读取时,这样复杂的数据结构最有意义。比如说

In [161]: dt = np.dtype([('Table', np.float64, (2, 2)),
                         ('Number', np.float),
                         ('String', '|S10')])

In [162]: txt="""0 0 0 0 0 astring
   .....: 1 2 3 4 0 another
   .....: 1 1 1 1 10 end
   .....: """

In [163]: A=np.genfromtxt(txt.splitlines(),dtype=dt)

In [164]: A
Out[164]: 
array([([[0.0, 0.0], [0.0, 0.0]], 0.0, 'astring'),
       ([[1.0, 2.0], [3.0, 4.0]], 0.0, 'another'),
       ([[1.0, 1.0], [1.0, 1.0]], 10.0, 'end')], 
      dtype=[('Table', '<f8', (2, 2)), ('Number', '<f8'), ('String', 'S10')])
[161]中的
:dt=np.dtype([('Table',np.float64,(2,2)),
(“数字”,名词性浮点数),
('String','S10'))
在[162]:txt=“”0 0 0 0 0 0 0 0
…1 2 3 4 0另一个
..:110结束
.....: """
在[163]中:A=np.genfromtxt(txt.splitlines(),dtype=dt)
在[164]中:A
出[164]:
数组([([[0.0,0.0],[0.0,0.0]],0.0,'astring'),
([1.0,2.0],[3.0,4.0],[0.0,'另一个'),
([1.0,1.0],[1.0,1.0],[10.0,'end'),

dtype=[('Table',如果我对numpy的理解正确,它会将其数据放入连续内存块中。因此我不确定numpy是否适合您的任务。您可能需要查看pytables(),它是为处理分层数据而设计的。@Dietrich:我不太清楚
numpy
,尽管它没有直接回答这个问题,但请您再详细一点好吗?请记住:我不想将这个数组写入文件(如h5或txt)。它只是用于内部操作。如果您的内部数据结构类似于链表(我不确定,但我认为python的列表是以这种方式实现的),则追加是有效的。如果您放大一个numpy数组,它将不得不将您的数据复制到一个新的内存位置,因为它无法在当前块后面找到可用内存。因此,我认为没有比您建议的更有效的方法了-除非您使用不同的数据结构:根据数据大小,python列表或dict可能就足够了用于大型阵列(RAM的重要部分),我建议使用pytables或数据库。@Dietrich:如果我理解正确,在扩展列表时使用列表更有效。您也建议使用pytables或数据库,但前提是它可能超过我的RAM?我不想在这里讨论这种情况。确切地说,我连续构建阵列的标准策略是使用在我的经验中,预分配足够大的数据块和移动原始数据(请参见
numpy.getbuffer()
)在大多数情况下可以忽略不计。
In [132]: x = np.zeros(3, dtype = [('Table', np.float64, (2, 2)),
                         ('Number', np.float),
                         ('String', '|S10')])

In [133]: x
Out[133]: 
array([([[0.0, 0.0], [0.0, 0.0]], 0.0, ''),
       ([[0.0, 0.0], [0.0, 0.0]], 0.0, ''),
       ([[0.0, 0.0], [0.0, 0.0]], 0.0, '')], 
      dtype=[('Table', '<f8', (2, 2)), ('Number', '<f8'), ('String', 'S10')])

In [134]: x['Table'].shape
Out[134]: (3, 2, 2)
In [137]: x['Table'][0,0,:]=[1,1]
In [156]: x={'Table': np.zeros((1,2,2),dtype=np.float64),
             'Number':np.zeros((1,)), 
             'String':['']}

In [157]: x
Out[157]: 
{'Number': array([ 0.]),
 'String': [''],
 'Table': array([[[ 0.,  0.],
        [ 0.,  0.]]])}

In [158]: x['Table'] =np.append(x['Table'],[1,2])

In [159]: x
Out[159]: 
{'Number': array([ 0.]),
 'String': [''],
 'Table': array([ 0.,  0.,  0.,  0.,  1.,  2.])}
In [161]: dt = np.dtype([('Table', np.float64, (2, 2)),
                         ('Number', np.float),
                         ('String', '|S10')])

In [162]: txt="""0 0 0 0 0 astring
   .....: 1 2 3 4 0 another
   .....: 1 1 1 1 10 end
   .....: """

In [163]: A=np.genfromtxt(txt.splitlines(),dtype=dt)

In [164]: A
Out[164]: 
array([([[0.0, 0.0], [0.0, 0.0]], 0.0, 'astring'),
       ([[1.0, 2.0], [3.0, 4.0]], 0.0, 'another'),
       ([[1.0, 1.0], [1.0, 1.0]], 10.0, 'end')], 
      dtype=[('Table', '<f8', (2, 2)), ('Number', '<f8'), ('String', 'S10')])