numpy append_field为2d形状的新字段给出形状错误 [英] numpy append_field gives shape error for new field with 2d shape
问题描述
我有一个结构化的numpy数组,我想使用recfunctions库 http://pyopengl.sourceforge.net/pydoc/numpy.lib.recfunctions. html 函数append_fields()或rec_append_fields()将字段添加一些 塑造它.但是,我得到一个错误:
I have a structured numpy array, I want to use the recfunctions library http://pyopengl.sourceforge.net/pydoc/numpy.lib.recfunctions.html function append_fields() or rec_append_fields() to append a field with some shape to it. However, I get an error:
ValueError:操作数不能与形状(10)(10,3)一起广播
ValueError: operands could not be broadcast together with shapes (10) (10,3)
其中10
是我现有数组的长度,而(3,)
是我要附加的字段的形状.
where 10
is the length of my existing array, and (3,)
is the shape of the field I want to append.
例如:
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)一起广播
ValueError: operands could not be broadcast together with shapes (4) (4,2)
有什么想法吗?我尝试使my_new_field
成为元组列表并放入dtype
具有正确形状的参数放入append_fields():
Any ideas? I tried making my_new_field
a list of tuples and putting a dtype
argument with the proper shape into the 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数组,结果似乎相同.
but that seems to end up the same once it gets converted to a numpy array.
当我使用rec_append_fields()而不是简单地使用时,这一切似乎都没有改变 append_fields()
None of this seems to change when I use rec_append_fields() instead of simply append_fields()
鉴于我的新字段与数组的形状不同,我想我无法实现所需的追加,这由 @radicalbiscuit .
In light of the fact that my new field doesn't have the same shape as my array, I suppose that my desired append is impossible, suggested by @radicalbiscuit.
In : my_new_field.shape
Out: (4, 2)
In : my_structured_array.shape
Out: (4,)
但是,为了说明我的观点,我在数组中包含了一个形状与原始数组不同的原始字段,这就是说,字段不必具有与结构化数组相同的形状.如何添加这样的字段?
But, I included one of the original fields in the array with shape different from the original array to make my point, which is that a field does not have to have the same shape as the structured array. How can I append a field like this?
In : my_structured_array['pos'].shape
Out: (4, 2)
In : my_new_field.shape
Out: (4, 2)
我应该注意,对于我的应用程序,我可以附加一个空字段,只要以后可以以某种方式更改形状即可.谢谢!
I should note that for my application, I can append an empty field as long as it's possible to somehow change the shape later. Thanks!
推荐答案
append_fields()
确实确实要求两个数组的形状相同.话虽如此,正如您在my_structured_array
中所意识到的那样,numpy确实支持子数组(即,字段本身可以是具有形状的数组).
append_fields()
does indeed require that the two arrays be the same shape. That being said, as you realized in my_structured_array
, numpy does support subarrays (that is, a field can itself be an array with a shape).
在您的情况下,我想您可能希望my_new_field
不是一个二维数组,而是一个带有dtype元素(例如dtype([('myfield', '<i8', (2,))])
)的一维数组(形状为shape(my_structured_array)
).例如,
In your case, I think you probably want my_new_field
not to be a two dimensional array, but instead be a one dimensional array (of shape shape(my_structured_array)
) with elements of dtype, e.g., dtype([('myfield', '<i8', (2,))])
. For example,
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
中,
Although the datatype is slightly inconvenient as myfield
is nested within new
,
>>> my_appended_array.dtype
dtype([('id', '|i1'), ('pos', '<f2', (2,)), ('new', [('myfield', '<i8', (2,))])])
但是,这很容易被强制消除,
This, however, is coerced away fairly easily,
>>> 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,))])
不过,不幸的是,我们不得不在这里重复my_structured_array
的dtype.乍一看似乎numpy.lib.recfunctions.flatten_descr
可以完成使dtype展平的工作,但不幸的是,它给出了一个元组,而不是np.dtype
所要求的列表.但是,将其输出强制为列表即可解决此问题,
Still, it's a bit unfortunate that we've had to repeat the dtype of my_structured_array
here. While at first glance it appears that numpy.lib.recfunctions.flatten_descr
could do the dirty work of flattening the dtype, it unfortunately gives a tuple and not a list as required by np.dtype
. Coercing its output to a list, however, works around this issue,
>>> np.dtype(list(np.lib.recfunctions.flatten_descr(my_appended_array.dtype)))
dtype([('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))])
这可以作为dtype传递给np.asarray
,使它在抵御my_structured_array.dtype
中的更改时变得更加健壮.
This can be passed as the dtype to np.asarray
, making things slightly more robust against changes in my_structured_array.dtype
.
实际上,诸如此类的细微不一致使处理记录阵列变得混乱.人们会觉得事情可以更加协调地融合在一起.
Indeed, minor inconsistencies such as this make working with record arrays messy business. One gets the feeling that things could fit together a bit more coherently.
事实证明,np.lib.recfunctions.merge_arrays
函数更适合这种合并,
It turns out that the np.lib.recfunctions.merge_arrays
function is much more amenable to this sort of merging,
>>> my_appended_array = merge_arrays([my_structured_array, my_new_field], flatten=True)
array([(0, [4.30078125, 3.19921875], [1, 1]),
(1, [1.400390625, 5.6015625], [1, 1]), (2, [6.0, 2.5], [1, 1]),
(3, [4.5, 5.3984375], [1, 1])],
dtype=[('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))])
这篇关于numpy append_field为2d形状的新字段给出形状错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!