NumPy - 记录数组
NumPy 中的记录数组
记录数组与结构化数组类似,但具有一个附加功能:它们允许您使用属性样式(点符号)和索引样式(字典样式)访问将字段作为属性访问。
这可以使代码更具可读性,更易于编写,尤其是在处理复杂数据结构时。
创建记录数组
我们可以通过多种方式创建记录数组,它们包括:-
- 通过转换现有的结构化数组
- 直接定义记录数组
- 使用 np.recarray 构造函数
将结构化数组转换为记录数组
创建记录数组的最简单方法是使用视图方法转换现有的结构化数组。这种方法可以让你保持数据的结构,同时获得访问属性的便利。
示例
在以下示例中,我们将在 NumPy 中将结构化数组转换为记录数组 -
import numpy as np # 创建结构化数组 structured_array = np.array([('Alice', 25, 5.5), ('Bob', 30, 6.0)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')]) # 将结构化数组转换为记录数组 record_array =structured_array.view(np.recarray) # 以以下方式访问字段属性 print(record_array.name) print(record_array.age)
以下是得到的输出 -
['Alice' 'Bob'] [25 30]
直接创建记录数组
创建记录数组的另一种方法是使用 np.rec.array() 函数直接定义它。此方法允许您从头创建一个记录数组,并指定数据和结构。
示例
在下面的示例中,我们直接在 NumPy 中创建一个记录数组,这样我们就可以使用点符号将字段作为属性访问 -
import numpy as np # 直接创建记录数组 record_array_direct = np.rec.array([('Charlie', 35, 5.8), ('David', 40, 6.2)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')]) # 将字段作为属性访问 print(record_array_direct.name) print(record_array_direct.height)
这将产生以下结果 -
['Charlie' 'David'] [5.8 6.2]
使用 np.recarray 构造函数
您还可以使用 np.recarray 构造函数创建记录数组。这种方法不太常见,但为特定用例提供了额外的灵活性。
示例
在此示例中,我们使用 np.recarray 构造函数创建一个记录数组,为其赋值数据,然后以属性的形式访问字段 name 和 age -
import numpy as np # 使用 np.recarray 定义记录数组 record_array_custom = np.recarray((2,), dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')]) # 将数据赋值给记录数组 record_array_custom[0] = ('Eve', 28, 5.7) record_array_custom[1] = ('Frank', 33, 6.1) # 将字段作为属性访问 print(record_array_custom.name) print(record_array_custom.age)
以下是上述代码的输出 -
['Eve' 'Frank'] [28 33]
访问记录数组的字段
创建记录数组后,您可以将其字段(即结构化数据的列)作为属性访问,从而简化数据操作和查询。
访问记录数组字段的最常用方法是使用 点 (.) 符号。记录数组的每个字段都将成为您可以直接访问的属性,类似于在 Python 中访问对象的属性。
示例:使用属性表示法访问字段
在下面的示例中,我们将创建一个包含字段 name、age 和 height 的记录数组,然后将每个字段作为记录数组的属性进行访问 -
import numpy as np # 创建记录数组 record_array = np.rec.array([('Alice', 25, 5.5), ('Bob', 30, 6.0)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')]) # 访问"name"字段 print(record_array.name) # 访问"age"字段 print(record_array.age) # 访问"height"字段 print(record_array.height)
输出结果如下 -
['Alice' 'Bob'] [25 30] [5.5 6. ]
示例:访问多个字段同时
除了访问单个字段外,您还可以同时访问多个字段。然而,与结构化数组不同,记录数组并不直接支持使用属性表示法同时访问字段。
相反,如果您想一次检索多个字段,则需要恢复到传统的索引方法,如下例所示 -
import numpy as np # 创建记录数组 record_array = np.rec.array([('Alice', 25, 5.5), ('Bob', 30, 6.0)], dtype=[('name', 'U10'), ('age', 'i4'), ('height', 'f4')]) # 使用索引访问多个字段 multiple_fields = record_array[['name', 'height']] print(multiple_fields)
执行上述代码后,我们得到以下输出 -
[('Alice', 5.5) ('Bob', 6. )]
修改记录数组的字段
修改 NumPy 记录数组中的字段允许您更新或更改结构化数据集中特定列(字段)内的数据。记录数组提供了一种使用属性样式访问来访问和修改字段的方法。
例如,您可以通过点 (.) 符号访问字段,然后应用所需的操作或赋值来修改记录数组中各个字段的值。
要向记录数组添加新字段,您可以结合使用 np.concatenat() 函数(或类似函数)来创建包含新增字段的新记录数组。
示例:更新字段
在下面的示例中,我们将创建一个包含字段"name"、"age"和"height"的记录数组。然后,我们更改特定记录的"年龄"和"身高" -
import numpy as np # 步骤 1:定义包含"姓名"、"年龄"和"身高"字段的初始记录数组 dtype = [('name', 'S20'), ('age', 'i1'), ('height', 'f4')] data = [('Alice', 30, 5.5), ('Bob', 25, 6.0), ('Charlie', 35, 5.8)] record_array = np.array(data, dtype=dtype) print("原始记录数组:") print(record_array) # 步骤 2:更新特定记录的字段 # 更新"年龄"和"身高" 'Bob' record_array[record_array['name'] == b'Bob']['age'] = 26 record_array[record_array['name'] == b'Bob']['height'] = 6.1 # 更新 'Charlie' 的 'age' record_array[record_array['name'] == b'Charlie']['age'] = 36 print(" 更新后的记录数组:") print(record_array)
结果如下 -
原始记录数组: [(b'Alice', 30, 5.5) (b'Bob', 25, 6. ) (b'Charlie', 35, 5.8)] 更新后的记录数组: [(b'Alice', 30, 5.5) (b'Bob', 25, 6. ) (b'Charlie', 35, 5.8)]
示例:添加新字段
在此示例中,我们首先定义一个仅包含"name"和"age"字段的记录数组。然后,我们创建一个新的记录数组,其中包含一个附加的"height"字段 -
import numpy as np # 步骤 1:定义包含字段"name"和"age"的初始记录数组 dtype = [('name', 'S20'), ('age', 'i1')] data = [('Alice', 30), ('Bob', 25), ('Charlie', 35)] record_array = np.array(data, dtype=dtype) print("原始记录数组:") print(record_array) # 步骤 2:定义一个包含新字段"height"的新数据类型 new_dtype = [('name', 'S20'), ('age', 'i1'), ('height', 'f4')] # 步骤 3:创建一个包含新数据类型的新记录数组,并使用零或默认值初始化 new_record_array = np.zeros(record_array.shape, dtype=new_dtype) # 步骤 4:将现有数据复制到新的记录数组中 for field in ['name', 'age']: new_record_array[field] = record_array[field] # 可选,为新字段"height"设置默认值 new_record_array['height'] = 0.0 print(" 包含新字段的记录数组:") print(new_record_array)
我们得到如下所示的输出 −
原始记录数组: [(b'Alice', 30) (b'Bob', 25) (b'Charlie', 35)] 包含新字段的记录数组: [(b'Alice', 30, 0.) (b'Bob', 25, 0.) (b'Charlie', 35, 0.)]
合并记录数组
在 NumPy 中,合并记录数组是指将多个记录数组合并或串联为一个记录数组。当您需要合并数据集或为现有数据集添加更多行时,此过程非常有用。
以下是合并记录数组的方法 -
- 连接: 沿现有轴(通常沿行)合并记录数组。
- 堆叠: 沿新轴堆叠记录数组,这对于添加新维度非常有用。
示例:连接记录数组
在下面的示例中,我们创建两个记录数组,然后沿行将它们连接起来,形成一个组合记录数组 -
import numpy as np # 定义两个包含字段"name"、"age"和"height"的记录数组 dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')] data1 = [('Alice', 25, 5.5), ('Bob', 30, 6.0)] data2 = [('Charlie', 35, 5.8), ('David', 40, 5.9)] # 创建记录数组 record_array1 = np.array(data1, dtype=dtype).view(np.recarray) record_array2 = np.array(data2, dtype=dtype).view(np.recarray) # 沿行(轴 0)连接记录数组 combined_record_array = np.concatenate((record_array1, record_array2)) print("合并记录array:") print(combined_record_array)
以下是得到的输出 -
组合记录数组: [('Alice', 25, 5.5) ('Bob', 30, 6. ) ('Charlie', 35, 5.8) ('David', 40, 5.9)]
示例:堆叠记录数组
在下面的示例中,我们创建两个记录数组,然后沿新轴堆叠它们以形成一个 3D 记录数组 -
import numpy as np # 定义两个包含字段"name"、"age"和"height"的记录数组 dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')] data1 = [('Alice', 25, 5.5), ('Bob', 30, 6.0)] data2 = [('Charlie', 35, 5.8), ('David', 40, 5.9)] # 创建记录数组 record_array1 = np.array(data1, dtype=dtype).view(np.recarray) record_array2 = np.array(data2, dtype=dtype).view(np.recarray) # 沿新轴堆叠记录数组 stacked_record_array = np.stack((record_array1, record_array2), axis=0) print("堆叠的记录array:") print(stacked_record_array)
这将产生以下结果 -
堆叠记录数组: [[('Alice', 25, 5.5) ('Bob', 30, 6. )] [('Charlie', 35, 5.8) ('David', 40, 5.9)]]
过滤记录数组
过滤记录数组意味着根据一个或一组条件从记录数组中选择特定的行或元素。
此过程用于提取符合特定条件的数据子集,这有助于我们进行更有针对性的分析和操作。
示例
在此示例中,我们创建一个布尔掩码来过滤包含"年龄"的记录从记录数组中取出大于"30"的数据 -
import numpy as np # 定义一个包含字段"name"、"age"和"height"的记录数组 dtype = [('name', 'U10'), ('age', 'i4'), ('height', 'f4')] data = [('Alice', 25, 5.5), ('Bob', 30, 6.0), ('Charlie', 35, 5.8), ('David', 40, 5.9)] record_array = np.array(data, dtype=dtype).view(np.recarray) # 为年龄大于 30 的数据创建一个布尔掩码 mask = record_array.age > 30 # 应用掩码过滤记录数组 filtered_record_array = record_array[mask] print("过滤后的记录数组 (年龄 > 30):") print(filtered_record_array)
以下是上述代码的输出 -
过滤后的记录数组 (年龄 > 30): [('Charlie', 35, 5.8) ('David', 40, 5.9)]