NumPy的复合数据类型(Structured Array)是一种强大的数据结构,允许在单个数组中存储异构数据(不同数据类型),类似于数据库表格或结构化记录。以下是其核心特性和使用方法的系统介绍:
🧱 一、核心概念
-
定义与特点
- 异构数据存储:复合数据类型允许每个数组元素包含多个字段(字段名 + 数据类型),例如存储学生信息(姓名:字符串、年龄:整数、成绩:浮点数)。
- 内存高效:基于NumPy的连续内存模型,访问速度快,适合大规模数据处理。
- 字段访问:支持通过字段名直接访问数据(如
array['age']),无需额外转换。
-
适用场景
- 表格数据处理(CSV、数据库导出)
- 科学计算中的多参数记录(如物理实验中时间、位置、温度等)
- 与Pandas DataFrame互操作(结构化数组可无缝转为DataFrame)
🔧 二、创建方法
1. 定义数据类型(dtype)
使用 np.dtype 指定字段结构,支持三种语法:
- 元组列表(最常用):
dtype = np.dtype([('name', 'U10'), ('age', 'i4'), ('height', 'f4')]) - 字典形式:
dtype = np.dtype({'names': ['name', 'age', 'height'], 'formats': ['U10', 'i4', 'f4']}) - 字符串简写:
dtype = np.dtype('U10, i4, f4') # 字段名自动分配为f0, f1, f2
注:U10 表示长度10的Unicode字符串,i4 为32位整数,f4 为32位浮点数。
2. 创建结构化数组
data = np.array([('Alice', 25, 1.65), ('Bob', 30, 1.80)], dtype=dtype)
输出:
[('Alice', 25, 1.65) ('Bob', 30, 1.80)]
3. 三种创建方式对比
| 方法 | 语法示例 | 优势 | 限制 |
|---|---|---|---|
| 元组列表 | dtype=[('name','U10'), ('age','i4')] | 字段名和类型明确 | 代码稍长 |
| 字典形式 | dtype={'names':['name','age'], 'formats':['U10','i4']} | 字段名集中管理 | 不支持嵌套字段 |
| 字符串简写 | dtype='U10, i4, f4' | 简洁 | 字段名默认为f0,f1,... |
🛠️ 三、数据操作
-
字段访问与修改
- 按字段提取列:
names = data['name'] # 输出:['Alice' 'Bob'] - 按行访问:
first_row = data[0] # 输出:('Alice', 25, 1.65) - 修改值:
data['age'] += 1 # 所有年龄+1 data[0]['height'] = 1.70 # 修改Alice身高
- 按字段提取列:
-
切片与条件筛选
# 筛选年龄>25的记录 filtered = data[data['age'] > 25] # 输出:[('Bob', 31, 1.80)] -
排序
# 按年龄升序排序 sorted_data = np.sort(data, order='age') # 多字段排序:先按年龄,再按身高 sorted_data = np.sort(data, order=['age', 'height'])
⚡ 四、高级特性
-
嵌套字段
支持字段内嵌套复合类型,适合存储树状结构:dtype_nested = np.dtype([ ('info', [('name', 'U10'), ('age', 'i4')]), # 嵌套字段 ('height', 'f4') ]) data_nested = np.array([(('Alice', 25), 1.65)], dtype=dtype_nested) -
多维字段
字段可以是多维数组,用于存储矩阵或张量:dtype_matrix = np.dtype([ ('id', 'i4'), ('matrix', 'f8', (3, 3)) # 每个元素包含3x3矩阵 ]) arr_matrix = np.zeros(2, dtype=dtype_matrix) -
字段增删(需重建数组)
# 添加体重字段 new_dtype = np.dtype(dtype.descr + [('weight', 'f4')]) new_data = np.zeros(data.shape, dtype=new_dtype) for field in data.dtype.names: new_data[field] = data[field] new_data['weight'] = [55, 70] # 填充新字段
💡 五、实际应用案例
学生成绩管理系统
# 定义数据类型
dtype = np.dtype([
('name', 'U10'),
('math', 'f4'),
('english', 'f4'),
('physics', 'f4')
])
# 创建数组
students = np.array([
('Alice', 85, 90, 88),
('Bob', 92, 85, 90)
], dtype=dtype)
# 计算平均分并添加新字段
avg_scores = np.mean([students['math'], students['english'], students['physics']], axis=0)
students = np.lib.recfunctions.append_fields(students, 'average', avg_scores, dtypes='f4')
输出:
[('Alice', 85., 90., 88., 87.67) ('Bob', 92., 85., 90., 89.0)]
⚠️ 六、注意事项
- 内存对齐
使用np.dtype(..., align=True)可强制内存对齐(类似C结构体),提升CPU访问效率 - 性能局限
复杂查询(如多条件筛选)效率低于Pandas,建议在数据清洗后转为结构化数组进行计算。 - 类型映射
复合类型可直接映射到C结构体,适合与C/Fortran库交互(如物理仿真、信号处理)。
💎 总结
NumPy复合数据类型通过结构化数组实现异构数据的高效存储,核心价值在于:
- 灵活建模:用单一数组管理多类型数据,避免多数组同步问题。
- 高性能计算:保留NumPy向量化操作优势,支持排序、筛选等复杂操作。
- 跨平台兼容:内存布局兼容C语言,无缝对接底层科学计算库。