NumPy - 操作结构化数组
在 NumPy 中操作结构化数组
在 NumPy 中操作结构化数组意味着根据您的需求修改、重新排列或处理这些数组中的数据。
结构化数组是一种特殊的数组,其中每个元素可以包含多个字段(例如姓名、年龄、身高),并且每个字段可以包含不同的数据类型(例如字符串、整数或浮点数)。
在 NumPy 中,您可以通过多种方式操作结构化数组 -
- 访问和修改字段
- 添加新字段
- 删除字段
- 对数组进行排序
- 过滤数组
- 合并数组
- 重塑数组
- 拆分数组
访问和修改字段
您可以使用字段名称作为键来访问结构化数组中的特定字段。这类似于访问字典中的值。例如,如果您有一个包含姓名、年龄和身高等字段的结构化数组,您可以访问年龄字段来检索数组中存储的所有年龄。
访问字段后,您还可以修改其值。例如,如果您想更新数组中某人的年龄,可以通过直接为年龄字段中的相应元素赋值来实现。
示例
在下面的示例中,我们将访问和修改结构化数组中的"年龄"字段。具体来说,我们将第一个元素(Alice)的年龄从 30 更新为 31,然后检索更新后的年龄 -
import numpy as np # 使用字段名称和数据类型定义 dtype dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')] # 使用一些初始数据创建结构化数组 data = [('Alice', 30, 5.6), ('Bob', 25, 5.8), ('Charlie', 35, 5.9)] structured_array = np.array(data, dtype=dtype) # 访问"age"字段 ages =structured_array['age'] print("修改前的年龄:", ages) #修改"age"字段 - 我们将 Alice 的年龄更新为 31 岁 structured_array['age'][0] = 31 # 再次访问"age"字段查看更改 print("修改后的年龄:",structured_array['age'])
以下是得到的输出 -
修改前的年龄:[30 25 35] 修改后的年龄:[31 25 35]
向结构化数组添加新字段
要向现有的结构化数组添加新字段,您需要创建一个包含新增字段的新数组,并将现有数据复制过来。
当您的数据结构发生变化并需要更多信息时,此过程可能是必要的。
示例
在此示例中,我们正在扩展现有的结构化数组,添加一个名为"Grade"的新字段。我们将现有数据复制到一个包含新增字段的新数组中,然后用相应的值填充新的"Grade"字段 -
import numpy as np # 现有的结构化数组 students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 35)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) # 定义一个新的数据类型,并添加一个字段"Grade" new_dtype = [('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4'), ('Grade', 'f4')] # 使用新的数据类型创建一个新的结构化数组 students_with_grade = np.zeros(students.shape, dtype=new_dtype) # 复制旧数据 for field in students.dtype.names: students_with_grade[field] = students[field] # 将数据添加到新的"Grade"字段 students_with_grade['Grade'] = [85.5, 90.0, 88.0] print(students_with_grade)
这将产生以下结果 -
[(1, 'Alice', 25, 85.5) (2, 'Bob', 23, 90. ) (3, 'Charlie', 35, 88. )]
从结构化数组中删除字段
要删除字段,您必须创建一个新的结构化数组,并修改其dtype以排除不需要的字段,然后将数据从原始数组复制到新数组。
示例
在下面的示例中,我们通过创建一个简化 dtype 的新数组来从现有的结构化数组中删除"Age"字段。然后,我们将原始数组中的相关字段复制到新数组中 -
import numpy as np # 原始结构化数组 students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 35)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) # 定义一个不包含"Age"字段的新数据类型 reduced_dtype = [('ID', 'i4'), ('Name', 'U10')] # 创建一个包含简化数据类型的新结构化数组 students_without_age = np.zeros(students.shape, dtype=reduced_dtype) # 复制相关字段 for field in students_without_age.dtype.names: students_without_age[field] = students[field] # 验证结果 print(students_without_age)
以下是上述代码的输出 -
[(1, 'Alice') (2, 'Bob') (3, 'Charlie')]
对结构化数组进行排序
在 NumPy 中,对结构化数组进行排序涉及根据一个或多个字段(列)对数组的元素(行)进行排序。
结构化数组可以包含多个不同数据类型的字段(例如,整数、浮点数、字符串),排序允许您以有意义的方式组织数据,例如按年龄、姓名或任何其他属性排列记录。
示例
在下面的示例中,我们使用带有"order"参数的 np.sort() 函数按"Age"字段对结构化数组进行排序。这将根据"年龄"值按升序重新排列记录 -
import numpy as np # 原始结构化数组 students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 35)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) # 按"年龄"排序 sorted_students = np.sort(students, order='Age') print(sorted_students)
获得的输出如下所示 -
[(2, 'Bob', 23) (1, 'Alice', 25) (3, 'Charlie', 35)]
过滤结构化数组中的数据
使用 NumPy 过滤结构化数组中的数据涉及选择符合特定条件的数据子集。
要过滤结构化数组,您可以使用布尔索引。这涉及根据应用于一个或多个字段的条件创建一个布尔掩码(一个包含 True 和 False 值的数组)。然后,您可以使用此掩码对原始数组进行索引,并提取所需的记录子集。
示例
在此示例中,我们使用布尔掩码筛选结构化数组,仅选择"Age"字段大于 25 的记录 -
import numpy as np # 原始结构化数组 students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 30)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) # 创建一个布尔掩码,其中 Age > 25 mask = students['Age'] > 25 # 应用掩码过滤数组 filtered_students = students[mask] print(filtered_students)
执行上述代码后,我们得到以下输出 -
[(3, 'Charlie', 30)]
合并结构化数组
在 NumPy 中,合并结构化数组用于沿单个轴(通常是行)合并具有相同数据类型的数组。
在 NumPy 中,np.concatenate() 函数用于沿现有轴连接数组。对于结构化数组,这要求所有数组共享相同的数据类型。
示例
在下面的示例中,我们使用 np.concatenate() 函数将两个具有相同数据类型的结构化数组合并为一个数组 -
import numpy as np # 定义两个具有相同数据类型的结构化数组 students1 = np.array([(1, 'Alice', 25), (2, 'Bob', 23)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) students2 = np.array([(3, 'Charlie', 30), (4, 'David', 28)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) # 连接数组 combined_students = np.concatenate((students1, students2)) print(combined_students)
结果如下 -
[(1, 'Alice', 25) (2, 'Bob', 23) (3, 'Charlie', 30) (4, 'David', 28)]
重塑结构化数组
在 NumPy 中重塑结构化数组涉及在保留数组数据结构的同时改变其形状。这意味着元素总数(行)在重塑前后保持不变。
在 NumPy 中,np.reshape() 函数用于更改结构化数组的形状。
示例
在下面的示例中,我们使用 np.reshape() 函数将一维结构化数组重塑为二维数组 -
import numpy as np # 定义一维结构化数组 students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 30)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) # 将数组从一维重塑为二维 reshaped_students = np.reshape(students, (3, 1)) print(reshaped_students)
这会将数组从单行记录转换为列格式,同时保留结构化数据,如下图所示 -
[[(1, 'Alice', 25)] [(2, 'Bob', 23)][(3, 'Charlie', 30)]]
拆分结构化数组
在 NumPy 中拆分结构化数组是指根据特定条件或大小将单个结构化数组划分为多个数组。
在 NumPy 中,np.split() 函数用于将数组拆分为多个沿指定轴拆分子数组。对于结构化数组,此函数要求数组沿元素可以均匀分布的轴进行拆分。
示例
在此示例中,我们使用 np.split() 函数将结构化数组拆分为两个相等的部分 -
import numpy as np # 定义结构化数组 students = np.array([(1, 'Alice', 25), (2, 'Bob', 23), (3, 'Charlie', 30), (4, 'David', 28)], dtype=[('ID', 'i4'), ('Name', 'U10'), ('Age', 'i4')]) # 将数组拆分成两个相等的部分 split_students = np.split(students, 2) print(split_students[0]) print(split_students[1])
我们得到如下所示的输出 −
[(1, 'Alice', 25) (2, 'Bob', 23)] [(3, 'Charlie', 30) (4, 'David', 28)]