numpy append_field为具有2d形状的新字段提供形状错误

时间:2012-12-10 05:17:53

标签: python numpy

我有一个结构化的numpy数组,我想使用recfunctions库 http://pyopengl.sourceforge.net/pydoc/numpy.lib.recfunctions.html 函数append_fields()或rec_append_fields()来附加一些字段 塑造它。但是,我收到一个错误:

  

ValueError:操作数无法与形状(10)(10,3)一起广播

其中10是我现有数组的长度,而(3,)是我要追加的字段的形状。

例如:

import numpy as np
from numpy.lib.recfunctions import append_fields


my_structured_array = np.array(
    zip([0,1,2,3],[[4.3,3.2],[1.4,5.6],[6.,2.5],[4.5,5.4]]),
    dtype=[('id','int8'),('pos','2float16')]
    )
my_new_field = np.ones(
    len(my_structured_array),
    dtype='2int8'
    )
my_appended_array = append_fields(
    my_structured_array,
    'new',
    data=my_new_field
    )
  

ValueError:操作数无法与形状(4)(4,2)

一起广播

有什么想法吗?我尝试将my_new_field列入元组并放入dtype 具有正确形状的参数进入append_fields():

my_new_field = len(my_structured_array)*[(1,1)]

my_appended_array = append_fields(
    my_structured_array,
    'new',
    data=my_new_field,
    dtype='2int8'
    )

但是一旦转换为numpy数组,它似乎也会变得相同。

当我使用rec_append_fields()而不是简单地使用时,这似乎都没有改变 append_fields()

编辑: 鉴于我的新场与我的阵列的形状不同,我认为@radicalbiscuit建议我不希望追加我想要的附加物。

In : my_new_field.shape
Out: (4, 2)

In : my_structured_array.shape
Out: (4,)

但是,我在数组中包含一个原始字段,其形状与原始数组不同,以表明我的观点,即字段不必具有与结构化数组相同的形状。我如何追加这样的字段?

In : my_structured_array['pos'].shape
Out: (4, 2)

In : my_new_field.shape
Out: (4, 2)

我应该注意,对于我的应用程序,我可以附加一个空字段,只要以后可以以某种方式改变形状。谢谢!

2 个答案:

答案 0 :(得分:6)

append_fields()确实要求两个数组的形状相同。话虽如此,正如你在my_structured_array中所认识到的那样,numpy确实支持子数组(也就是说,一个字段本身可以是一个带有形状的数组)。

在您的情况下,我认为您可能希望my_new_field不是二维数组,而是具有dtype元素的一维数组(形状shape(my_structured_array)),例如{{1} 1}}。例如,

dtype([('myfield', '<i8', (2,))])

会屈服,

import numpy as np
from numpy.lib.recfunctions import append_fields

my_structured_array = np.array(
    zip([0,1,2,3],[[4.3,3.2],[1.4,5.6],[6.,2.5],[4.5,5.4]]),
    dtype=[('id','int8'),('pos','2float16')]
    )

my_new_field = np.ones(
    len(my_structured_array),
    dtype=[('myfield', 'i8', 2)]
    )

my_appended_array = append_fields(
    my_structured_array,
    'new',
    data=my_new_field
    )

虽然数据类型稍微不方便,因为>>> my_appended_array[0] (0, [4.30078125, 3.19921875], ([1, 1],)) 嵌套在myfield中,

new
然而,这很容易被强制剥夺,

>>> my_appended_array.dtype
dtype([('id', '|i1'), ('pos', '<f2', (2,)), ('new', [('myfield', '<i8', (2,))])])

但是,我们不得不在这里重复>>> np.asarray(my_appended_array, dtype=[('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))]) array([(0, [4.30078125, 3.19921875], [0, 0]), (1, [1.400390625, 5.6015625], [0, 0]), (2, [6.0, 2.5], [0, 0]), (3, [4.5, 5.3984375], [0, 0])], dtype=[('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))]) 的dtype,这有点不幸。虽然乍一看似乎my_structured_array可以完成扁平化dtype的肮脏工作,但遗憾的是它提供了一个元组而不是numpy.lib.recfunctions.flatten_descr所要求的列表。然而,将其输出强制转换为列表可解决此问题,

np.dtype

这可以作为dtype传递给>>> np.dtype(list(np.lib.recfunctions.flatten_descr(my_appended_array.dtype))) dtype([('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))]) ,使np.asarray的变化更加强大。

事实上,像这样的轻微不一致使得与记录阵列混乱的业务。人们感觉事物可以更加连贯地融合在一起。

编辑: 事实证明,my_structured_array.dtype函数更适合这种合并,

np.lib.recfunctions.merge_arrays

答案 1 :(得分:2)

append_fields()要求两个数组的形状相同,在这种情况下它们不是。打印出两个阵列将有助于显而易见:

>>> my_structured_array
array([(0, [4.30078125, 3.19921875]), (1, [1.400390625, 5.6015625]),
       (2, [6.0, 2.5]), (3, [4.5, 5.3984375])], 
      dtype=[('id', '|i1'), ('pos', '<f2', (2,))])
>>> my_new_field
array([[1, 1],
       [1, 1],
       [1, 1],
       [1, 1]], dtype=int8)

如您所见,my_structured_array是一个长度为4的数组,其中每个元素都是一个包含两个对象的元组,一个int和一个包含两个浮点数的列表。

另一方面,

my_new_field是一个长度为4的数组,其中每个元素都是两个整数的列表。这就像尝试添加苹果和橘子一样。

使你的阵列形状相同,它们会加在一起。