直接用 np.array(dict) 失败是因为嵌套字典非 NumPy 原生支持,会退化为 dtype=object 一维数组或报 ValueError;必须先扁平化为字段对齐的字典列表并显式定义结构化 dtype。

为什么直接用 np.array(dict) 会失败
嵌套字典不是 NumPy 原生支持的输入类型,np.array() 遇到嵌套结构(比如 {"a": {"x": 1, "y": 2}, "b": {"x": 3, "y": 4}})会退化为 dtype=object 的一维数组,完全丢失结构化访问能力。更糟的是,如果各子字典字段不一致(比如有的缺 "y"),还会触发 ValueError: setting an array element with a sequence。
必须先扁平化再定义 dtype 元组
NumPy 结构化数组要求所有记录字段名、类型、顺序严格对齐。嵌套字典得先展开成“每行一条记录”的列表,每条记录是普通字典(非嵌套),字段名作为顶层 key。
- 用递归或
jsonpath-ng提取路径如"a.x"→ 改写为合法字段名"a_x" - 统一字段类型:数值优先用
np.float64,字符串用np.dtype("U32")(避免object) -
dtype必须是元组列表,例如[("a_x", "f8"), ("a_y", "f8"), ("b_x", "f8")],不能传字典 - 构造数据时用
np.array(data_list, dtype=dtype),data_list是字典列表,每个字典只含 flat 后的 key
示例:
data = [{"a": {"x": 1.0, "y": 2.0}, "b": {"x": 3.0}}]
flat_data = [{"a_x": 1.0, "a_y": 2.0, "b_x": 3.0, "b_y": np.nan}]
dtype = [("a_x", "f8"), ("a_y", "f8"), ("b_x", "f8"), ("b_y", "f8")]
arr = np.array(flat_data, dtype=dtype)
嵌套层级深时,dtype 字段名容易冲突或过长
比如 {"user": {"profile": {"name": "Alice"}, "stats": {"count": 5}}} 扁平后变成 "user_profile_name" 和 "user_stats_count" —— 字段名太长不仅难读,还可能超出 NumPy 对字段名长度的隐式限制(实际影响不大,但调试时看着累)。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
立即学习“Python免费学习笔记(深入)”;
- 建议用下划线分隔 + 缩写,如
"usr_prof_name",提前约定命名规则 - 避免用点号(
.)或空格,NumPy 字段名只支持字母、数字、下划线,且不能以数字开头 - 如果原始嵌套中存在动态 key(如
{"items": {"001": {...}, "002": {...}}}),必须转为固定字段(如"item_001_x")或改用object列存整个子字典(牺牲结构化查询能力)
缺失值处理不当会导致 dtype 推断错误
NumPy 在构造结构化数组时,若某字段在部分记录中缺失(None 或根本没出现),而你又没显式指定该字段类型,它可能把整列判为 object,后续无法做数值运算。
- 务必在
flat_data构造阶段补全所有字段,缺失值填np.nan(数值)、""(字符串)或0(整型) - 字符串字段别用
np.nan,否则 dtype 会变成object;改用np.dtype("U32")并填空字符串 - 检查最终
arr.dtype是否全是预期类型,尤其注意有没有意外的|O(object)
最易忽略的是:嵌套字典键名本身含 Unicode 或特殊字符(如中文、连字符),这些无法直接作为字段名,必须清洗 —— 不处理就报 ValueError: illegal field name。

















