numpy append_field为2d形状的新字段给出形状错误 [英] numpy append_field gives shape error for new field with 2d shape

查看:142
本文介绍了numpy append_field为2d形状的新字段给出形状错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构化的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆