5

私は構造化された 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配列に変換されると、それは同じになるようです。

単に append_fields() の代わりに rec_append_fields() を使用しても、これは何も変わらないようです

編集:私の新しいフィールドが私の配列と同じ形状を持っていないという事実に照らして、私は@radicalbiscuitによって提案された私の望ましい追加は不可能だと思います。

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

In : my_structured_array.shape
Out: (4,)

ただし、元の配列とは異なる形状の元のフィールドの 1 つを配列に含めて、フィールドが構造化配列と同じ形状である必要はありません。このようなフィールドを追加するにはどうすればよいですか?

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

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

私のアプリケーションでは、後で何らかの方法で形状を変更できる限り、空のフィールドを追加できることに注意してください。ありがとう!

4

2 に答える 2

6

append_fields()実際、2 つの配列が同じ形状である必要があります。そうは言っても、 で気づいたようにmy_structured_array、numpy は部分配列をサポートしています (つまり、フィールド自体が形状を持つ配列になることができます)。

あなたの場合、おそらくmy_new_field2 次元配列ではなくshape(my_structured_array)、dtype の要素を持つ ( shape の) 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です。一見するとnumpy.lib.recfunctions.flatten_descr、dtype を平坦化するという厄介な作業を行うことができるように見えますが、残念ながら、np.dtype. ただし、その出力をリストに強制すると、この問題を回避できます。

>>> np.dtype(list(np.lib.recfunctions.flatten_descr(my_appended_array.dtype)))
dtype([('id', '|i1'), ('pos', '<f2', (2,)), ('myfield', '<i8', (2,))])

これは に dtype として渡すことができnp.asarraymy_structured_array.dtype.

実際、このような小さな不一致により、レコード配列の操作が煩雑になります。物事がもう少し首尾一貫して合うように感じることができます。

編集:np.lib.recfunctions.merge_arrays関数はこの種のマージにはるかに適していることがわかりました 。

 >>> 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,))])
于 2012-12-10T15:42:58.710 に答える
2

append_fields()では、2 つの配列が同じ形状である必要がありますが、この場合はそうではありません。2 つの配列を印刷すると、明らかになります。

>>> 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 と 2 つの float のリストの 2 つのオブジェクトを含むタプルです。

my_new_field一方、各要素が 2 つの int のリストである長さ 4 の配列です。リンゴとオレンジを追加しようとしているようなものです。

配列を同じ形状にすると、それらが加算されます。

于 2012-12-10T06:48:35.340 に答える