在处理复杂数据时,尤其是包含多种不同类型信息的数据集(如表格数据或数据库记录),NumPy 的普通数组可能显得力不从心。为了解决这一问题,NumPy 提供了结构化数组(Structured Array),允许为数组的每一列或字段分配不同的数据类型。结构化数组可以看作是结合了 NumPy 数组高效性和数据库记录灵活性的一种数据结构。
结构化数组是 NumPy 的一种特殊数组,它允许定义多个字段,每个字段可以具有不同的数据类型和名称。结构化数组类似于数据库中的表格,每行代表一条记录,每列代表一个字段。
在创建结构化数组之前,需要定义每个字段的名称、数据类型和可选的形状。
NumPy 提供了灵活的方式定义结构化数据类型:
import numpy as np
# 定义结构化数据类型
dtype = np.dtype([
('Name', 'U10'), # 名称字段,Unicode字符串,长度10
('Age', 'i4'), # 年龄字段,32位整数
('Height', 'f4') # 身高字段,32位浮点数
])
通过定义好的数据类型,可以创建结构化数组:
# 创建结构化数组
data = np.array([
('Alice', 25, 1.65),
('Bob', 30, 1.80),
('Charlie', 35, 1.75)
], dtype=dtype)
print("结构化数组:\n", data)
输出:
结构化数组:
[('Alice', 25, 1.65) ('Bob', 30, 1.8) ('Charlie', 35, 1.75)]
在这个数组中,每行包含三个字段:Name、Age 和 Height。
结构化数组支持通过字段名和索引访问数据,同时保留 NumPy 数组的切片特性。
可以通过字段名直接访问特定字段的数据:
# 访问单个字段
print("名称字段:", data['Name'])
print("年龄字段:", data['Age'])
输出:
名称字段: ['Alice' 'Bob' 'Charlie']
年龄字段: [25 30 35]
通过索引可以访问单行数据:
# 访问第2行数据
print("第二行数据:", data[1])
输出:
第二行数据: ('Bob', 30, 1.8)
结构化数组支持常规的切片操作:
# 获取前两行
print("前两行数据:\n", data[:2])
输出:
前两行数据:
[('Alice', 25, 1.65) ('Bob', 30, 1.8)]
可以直接修改字段或特定位置的值:
# 修改单个字段的值
data['Age'] += 1
print("增加年龄后的数据:\n", data)
# 修改单条记录
data[0] = ('Alice', 26, 1.66)
print("修改第一行后的数据:\n", data)
输出:
增加年龄后的数据:
[('Alice', 26, 1.65) ('Bob', 31, 1.8) ('Charlie', 36, 1.75)]
修改第一行后的数据:
[('Alice', 26, 1.66) ('Bob', 31, 1.8) ('Charlie', 36, 1.75)]
NumPy 的结构化数组不支持直接添加字段,但可以通过重建数组实现:
# 添加新的字段
new_dtype = np.dtype([
('Name', 'U10'),
('Age', 'i4'),
('Height', 'f4'),
('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, 68]
print("新增字段后的数据:\n", new_data)
输出:
新增字段后的数据:
[('Alice', 26, 1.66, 55.) ('Bob', 31, 1.8, 70.)
('Charlie', 36, 1.75, 68.)]
可以根据条件筛选数据:
# 筛选年龄大于30的记录
filtered_data = data[data['Age'] > 30]
print("筛选结果:\n", filtered_data)
输出:
筛选结果:
[('Bob', 31, 1.8) ('Charlie', 36, 1.75)]
通过numpy.sort或numpy.argsort对结构化数组进行排序:
# 按年龄排序
sorted_data = np.sort(data, order='Age')
print("按年龄排序后的数据:\n", sorted_data)
输出:
按年龄排序后的数据:
[('Alice', 26, 1.66) ('Bob', 31, 1.8) ('Charlie', 36, 1.75)]
可以指定多个字段进行排序:
# 按年龄和身高排序
sorted_data = np.sort(data, order=['Age', 'Height'])
print("按年龄和身高排序后的数据:\n", sorted_data)
以下是一个学生成绩管理的实际案例,展示结构化数组的应用。
# 创建学生成绩数据
student_dtype = np.dtype([
('StudentID', 'i4'),
('Name', 'U10'),
('Math', 'i4'),
('English', 'i4'),
('Science', 'i4')
])
students = np.array([
(1, 'Alice', 85, 78, 92),
(2, 'Bob', 89, 82, 88),
(3, 'Charlie', 95, 88, 91),
(4, 'David', 72, 68, 75)
], dtype=student_dtype)
# 添加总分和平均分
students_with_scores = np.zeros(students.shape, dtype=[
('StudentID', 'i4'),
('Name', 'U10'),
('Math', 'i4'),
('English', 'i4'),
('Science', 'i4'),
('Total', 'i4'),
('Average', 'f4')
])
for field in students.dtype.names:
students_with_scores[field] = students[field]
students_with_scores['Total'] = students['Math'] + students['English'] + students['Science']
students_with_scores['Average'] = students_with_scores['Total'] / 3
print("添加总分和平均分后的数据:\n", students_with_scores)
# 按总分排序
sorted_students = np.sort(students_with_scores, order='Total')
print("按总分排序后的学生数据:\n", sorted_students)
NumPy 的结构化数组为处理复杂数据提供了高效灵活的解决方案。通过为每个字段指定数据类型,结构化数组能够高效管理和操作类似表格的数据集。无论是数据查询、排序还是条件筛选,结构化数组都表现出色。
如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!