3

私が理解していることから、NumPy 配列をネイティブ Python リストに変換する推奨される方法は、ndarray.tolist.

残念ながら、構造化された配列を使用する場合、これは再帰的に機能しないようです。実際、いくつかのndarrayオブジェクトは結果のリストで参照されており、変換されていません:

>>> dtype = numpy.dtype([('position', numpy.int32, 3)])
>>> values = [([1, 2, 3],)]
>>> a = numpy.array(values, dtype=dtype)
>>> a.tolist()
[(array([1, 2, 3], dtype=int32),)]

この問題を回避するための簡単な関数を作成しました。

def array_to_list(array):
    if isinstance(array, numpy.ndarray):
        return array_to_list(array.tolist())
    elif isinstance(array, list):
        return [array_to_list(item) for item in array]
    elif isinstance(array, tuple):
        return tuple(array_to_list(item) for item in array)
    else:
        return array

これを使用すると、期待される結果が得られます。

>>> array_to_list(a) == values
True

この関数の問題は、ndarray.tolist出力する各リスト/タプルを再作成することにより、ジョブを複製することです。最適ではありません。

質問は次のとおりです。

  • この動作はndarray.tolist予期されるものですか?
  • これを実現するためのより良い方法はありますか?
4

1 に答える 1

0

これを少し一般化するために、別のフィールドを dtype に追加します

In [234]: dt = numpy.dtype([('position', numpy.int32, 3),('id','U3')])

In [235]: a=np.ones((3,),dtype=dt)

表示はreprリストとタプルを使用します:

In [236]: a
Out[236]: 
array([([1, 1, 1], '1'), ([1, 1, 1], '1'), ([1, 1, 1], '1')], 
  dtype=[('position', '<i4', (3,)), ('id', '<U3')])

ただし、tolistお気づきのように、要素は展開されません。

In [237]: a.tolist()
Out[237]: [(array([1, 1, 1]), '1'), (array([1, 1, 1]), '1'), 
   (array([1, 1, 1]), '1')]

同様に、そのような配列は、完全にネストされたリストとタプルから作成できます。

In [238]: a=np.array([([1,2,3],'str')],dtype=dt)
In [239]: a
Out[239]: 
array([([1, 2, 3], 'str')], 
  dtype=[('position', '<i4', (3,)), ('id', '<U3')])
In [240]: a.tolist()
Out[240]: [(array([1, 2, 3]), 'str')]

この不完全な再帰から配列を再作成しても問題はありません。

In [250]: np.array(a.tolist(),dtype=dt)
Out[250]: 
array([([1, 2, 3], 'str')], 
      dtype=[('position', '<i4', (3,)), ('id', '<U3')])

このような構造化された配列を使用する人を初めて見ましtolistたが、私はそれほど驚くことではありません。開発者がこれをバグと見なすかどうかはわかりません。

この配列の純粋なリスト/タプル レンダリングが必要なのはなぜですか?

numpy/lib/recfunctions.pyこれに対処する機能があるのだろうか。

于 2016-09-15T04:04:49.497 に答える