2

dtype文字列のフィールドがあり、長さが異なるレコード配列を連結しようとすると、連結は失敗します。

次の例でわかるように、連結は「f1」が同じ長さの場合は機能しますが、そうでない場合は失敗します。

In [1]: import numpy as np

In [2]: a = np.core.records.fromarrays( ([1,2], ["one","two"]) )

In [3]: b = np.core.records.fromarrays( ([3,4,5], ["three","four","three"]) )

In [4]: c = np.core.records.fromarrays( ([6], ["six"]) )

In [5]: np.concatenate( (a,c) )
Out[5]: 
array([(1, 'one'), (2, 'two'), (6, 'six')], 
      dtype=[('f0', '<i8'), ('f1', '|S3')])

In [6]: np.concatenate( (a,b) )
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/u/jegannas/<ipython console> in <module>()

TypeError: expected a readable buffer object

ただし、文字列のサイズは異なりますが、(レコードではなく)配列を連結するだけで成功します。

In [8]: np.concatenate( (a['f1'], b['f1']) )
Out[8]: 
array(['one', 'two', 'three', 'four', 'three'], 
      dtype='|S5')

これは、レコードを連結するときの連結のバグですか、それとも予想される動作ですか。私はこれを克服するために次の方法しか考えていません。

In [10]: np.concatenate( (a.astype(b.dtype), b) )
Out[10]: 
array([(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'three')], 
      dtype=[('f0', '<i8'), ('f1', '|S5')]

しかし、ここでの問題は、すべての再配列を実行する必要があることです。連結して最大の文字列長を見つけ、それを使用する必要があります。レコード配列に複数の文字列列がある場合は、他のいくつかのことも追跡する必要があります。

少なくとも今のところ、これを克服するための最良の方法は何だと思いますか?

4

3 に答える 3

6

完全な回答を投稿します。Pierre GMがモジュールを提案したように:

import numpy.lib.recfunctions

解決策を提供します。ただし、必要なことを実行する関数は次のとおりです。

numpy.lib.recfunctions.stack_arrays((a,b), autoconvert=True, usemask=False)

usemask=Falseおそらく使用していないマスクされた配列の作成を避けるためです。重要なことは、からへのautoconvert=True変換を強制することです)。adtype "|S3""|S5"

于 2012-08-23T12:25:18.113 に答える
2

dtypeを指定しない場合、np.rec.fromarrays(aka np.core.records.fromarrays)はdtypeを推測しようとします。したがって、

In [4]: a = np.core.records.fromarrays( ([1,2], ["one","two"]) )

In [5]: a
Out[5]: 
rec.array([(1, 'one'), (2, 'two')], 
      dtype=[('f0', '<i4'), ('f1', '|S3')])

列のdtypeがf13バイトの文字列であることに注意してください。

np.concatenate( (a,b) )numpyはのdtypeを認識し、異なるため、a連結できませんb。小さい文字列のdtypeを、大きい文字列に一致するように変更しません。

すべての配列で機能する最大文字列サイズがわかっている場合は、最初からdtypeを指定できます。

In [9]: a = np.rec.fromarrays( ([1,2], ["one","two"]), dtype = [('f0', '<i4'), ('f1', '|S8')])

In [10]: b = np.core.records.fromarrays( ([3,4,5], ["three","four","three"]), dtype = [('f0', '<i4'), ('f1', '|S8')])

その後、連結は希望どおりに機能します。

In [11]: np.concatenate( (a,b))
Out[11]: 
array([(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'three')], 
      dtype=[('f0', '<i4'), ('f1', '|S8')])

文字列の最大長が事前にわからない場合は、dtypeを「object」として指定できます。

In [35]: a = np.core.records.fromarrays( ([1,2], ["one","two"]), dtype = [('f0', '<i4'), ('f1', 'object')])

In [36]: b = np.core.records.fromarrays( ([3,4,5], ["three","four","three"]), dtype = [('f0', '<i4'), ('f1', 'object')])

In [37]: np.concatenate( (a,b))
Out[37]: 
array([(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'three')], 
      dtype=[('f0', '<i4'), ('f1', '|O4')])

'|Sn'これは、 (一部の整数の) dtypeほどスペース効率が良くありませんnが、少なくともconcatenate操作を実行できるようになります。

于 2012-08-23T11:32:42.073 に答える
2

あなたnumpy.lib.recfunctions.merge_arraysのために働きますか?recfunctionsあまり宣伝されていない、あまり知られていないサブパッケージです。少し不格好ですが、場合によっては役立つ可能性があります。

于 2012-08-23T11:34:44.397 に答える