如何让NumPy将列表的列表转为元素为列表的一维object数组?
问题描述
我有一个包含自定义Python对象(命名为MyClass)的列表,该对象可被解析为多维NumPy数组,但我希望将此列表转换为元素为MyClass对象的NumPy数组,而非将MyClass解析为内部的NumPy数组。用普通列表替代MyClass举例:
a = [1, 2, 3] b = [4, 5, 6] data = [a, b]
目前通过循环赋值能实现需求:
import numpy as np arr = np.empty(len(data), dtype=object) for i,v in enumerate(data): arr[i] = v assert arr.shape == (len(data),) # 运行正常
但使用np.array(data, dtype=object)无法得到预期结果:
arr = np.array(data, dtype=object) print(arr.shape) # 输出(2,3),而我需要(2,)
想知道:
- 有没有办法限制NumPy不深入解析内部列表,直接将其作为数组元素?
- 为何设置
dtype=object无法实现这一点? - 希望避免使用枚举循环的方式。
解答
为什么dtype=object达不到预期?
NumPy的np.array()在创建数组时,会优先尝试将输入的嵌套序列解析为多维数组——哪怕你指定了dtype=object。当输入的所有子序列长度一致时(比如例子里的两个列表都是长度3),NumPy会默认推导成二维数组,把每个子序列的元素拆出来作为数组的底层元素,而非将整个子序列当作单个object元素。dtype=object只是让最终数组的元素类型为object,但无法阻止NumPy先完成多维结构的解析。
无需循环的解决方案
方法1:构造单元素嵌套列表
通过把每个子元素包装成单元素列表,让NumPy无法直接解析成多维数组,从而强制它将每个原列表作为单个object元素:
import numpy as np arr = np.array([[x] for x in data], dtype=object).ravel() print(arr.shape) # 输出(2,)
ravel()负责把临时的二维数组展平为一维,最终数组的每个元素都是原列表对象。
方法2:使用np.fromiter
np.fromiter()会直接从可迭代对象创建指定类型的数组,它不会深入解析嵌套序列,完美匹配需求:
import numpy as np arr = np.fromiter(data, dtype=object) print(arr.shape) # 输出(2,)
这个方法最简洁,完全不需要循环操作。
内容的提问来源于stack exchange,提问作者Doron Behar
相关产品推荐
相关产品推荐

