gpt4 book ai didi

python - NumPy 结构化数组的真正递归 `tolist()`

转载 作者:行者123 更新时间:2023-12-02 10:02:16 29 4
gpt4 key购买 nike

据我了解,将 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 的这种行为是否符合预期?
  • 有更好的方法来实现这一点吗?

最佳答案

为了概括这一点,我将向您的数据类型添加另一个字段

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 中是否有一个函数可以解决这个问题。

关于python - NumPy 结构化数组的真正递归 `tolist()`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39502461/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com