NumPy中union dtype是什么?如何定义并优化数组dtype?
假设我有如下数组:
x = np.array([["Hello", 0, 1], ["World", 1, 2]], dtype=np.object_)
我希望优化该数组的dtype定义,具体来说,让数组为每个元素分配最大元素所需的字节数,这就是我理解的类型“union”。
Stack Overflow的相关回答提到NumPy 1.7+支持union dtype,官方文档相关章节指出(base_dtype, new_dtype)格式可定义类似C语言union的重叠字段结构体dtype,但不推荐此用法,更建议使用“union机制”。
但我不清楚“union机制”具体指什么,且无法用(np.object_, (np.uint32, np.uint32))这种格式,因为np.object_不能作为base_dtype。我猜测是让结构化数组字段重叠来实现union特性,但官方文档的描述让我对定义union type的首选机制感到困惑。
什么是NumPy的“union机制”
官方推荐的union实现方式,是通过结构化dtype的字段重叠来实现——给每个字段指定相同的offset(内存偏移量,通常设为0),让多个字段共享同一块内存空间。整个dtype的内存大小由占用字节数最大的字段决定,完全匹配你“为每个元素分配最大元素所需字节数”的需求。
针对你的场景的具体实现
确定兼容类型及字节大小
你的数组包含两种元素:固定长度字符串(如"Hello"对应NumPy的U5类型,占用20字节)、无符号32位整数(uint32,占用4字节),最大字节数为20字节。定义union dtype
通过设置字段偏移量为0,让字符串和数值字段共享内存:
import numpy as np union_dtype = np.dtype([ ('str_val', 'U5', 0), # 存储字符串的字段,偏移量0 ('num_val', np.uint32, 0) # 存储数值的字段,偏移量0,与str_val重叠 ])
- 创建并填充数组
生成对应形状的数组后,通过字段名分别赋值字符串和数值:
# 创建2行3列的空数组,dtype为自定义union类型 x_union = np.empty((2, 3), dtype=union_dtype) # 赋值字符串元素 x_union[0, 0]['str_val'] = "Hello" x_union[1, 0]['str_val'] = "World" # 赋值数值元素 x_union[0, 1]['num_val'] = 0 x_union[0, 2]['num_val'] = 1 x_union[1, 1]['num_val'] = 1 x_union[1, 2]['num_val'] = 2
为什么不能用(np.object_, ...)格式
NumPy要求union的base_dtype必须是固定内存大小的类型,而np.object_本质是指向任意对象的指针:它自身的大小固定(如64位系统为8字节),但指向的内容大小不固定,因此无法作为base_dtype使用。
补充说明
官方文档中提到的(base_dtype, new_dtype)是旧的兼容写法,现在已不推荐使用;而你猜测的“结构化数组字段重叠”,正是官方推荐的“union机制”的核心实现方式。
内容的提问来源于stack exchange,提问作者bzm3r

