根据我的理解,将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
的预期行为吗?答案 0 :(得分: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
中是否存在解决此问题的功能。