「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」
前言
python numpy 提供多维数组对象、数组快速操作的方法的科学计算基础库,其包名普通数组和结构化数组。我们前面已经学习了结构化数组相关知识如:
我们都知道,numpy 普通数组要求其数据类型必须是同质的,但是其结构化数组类似于 python 内置数组类型字典,使用 numpy.dtype 方法定义使数组中可以实现包含不同数据类型的元素。
结构化数组数据类型是一系列字段的集合。每个字段都由name、type 及 offset组成。其中,字段偏移量是可选项。
我们在上一期学习完结构化数组索引内容后,可知结构化数组与普通数组一样,支持索引,可以访问单个字段、多个字段数据外,还可以支持标量访问数。由于结构化数组的索引是可以变的,返回的结果是原始数组的视图。
结构化数组的创建除了可以使用numpy.array()方法外,numpy还提供了numpy.record()方法创建记录数组,可以直接通过属性访问字段。
本期,我们来学习记录结构化数组的相关方法,Let's go~
1. 记录数组
-
什么是记录数组?
numpy 提供一种标准数组子类 numpy.recarray 来进行创建ndarray对象。
通过 numpy.recarray 创建的数组,不仅可以通过索引访问结构化数组的字段还可以通过属性进行访问。
并且记录数组使用的特殊的数据类型numpy.record,其允字段访问作为属性查找的数据类型标量
-
记录数组的特点
- 记录数组可以允许字段作为数组成员访问
- 通过numpy.recarray创建的结构化数组可以通过.tolist()转换成普通数组
- 可以通过numpy.rec.array()方法将结构化数组转换成记录数组
2. 记录数组的创建
numpy.rec 模块提供了从各种对象创建记录数组的功能。
-
使用numpy.rec.array()方法创建记录数组
记录数据直接引用字段名称来访问数组中数据
>>> recarr = np.rec.array([("Tom",12,"Beijing"),("Anne",10,"Guangzhou"),("Kenty",15,"Shengzheng")],dtype=[("name","U5"),("age","i8" ),("address","U5")]) >>> recarr.name array(['Tom', 'Anne', 'Kenty'], dtype='<U5') >>> recarr.age array([12, 10, 15], dtype=int64) >>> recarr.address array(['Beiji', 'Guang', 'Sheng'], dtype='<U5') >>> recarr.address[1:2] array(['Guang'], dtype='<U5') >>> recarr[1:2] rec.array([('Anne', 10, 'Guang')], dtype=[('name', '<U5'), ('age', '<i8'), ('address', '<U5')]) >>> recarr[1:2].address array(['Guang'], dtype='<U5') >>> recarr[1].address 'Guang' >>> 复制代码
如果非记录数组,直接引用字段名访问,系统会抛出异常
>>> arr = np.array([("Tom",12,"Beijing"),("Anne",10,"Guangzhou"),("Kenty",15,"Shengzheng")],dtype=[("name","U5"),("age","i8"),("add ress","U5")]) >>> arr.name Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'numpy.ndarray' object has no attribute 'name' >>> 复制代码
-
使用numpy.rec.array()方法将参数转换为记录数组
通过numpy.array创建的结构化数组,通过rec.array方法转换为记录数组
>>> arr = np.array([("Tom",12,"Beijing"),("Anne",10,"Guangzhou"),("Kenty",15,"Shengzheng")],dtype=[("name","U5"),("age","i8"),("add ress","U5")]) >>> recarr = np.rec.array(arr) >>> 复制代码
-
使用视图方式获取结构化数组的记录数组
除了使用rec.array方法创建数组外,我们也可以使用 numpy.view 视图方法来创建
- 使用视图方法时,通过type字段定义为np.recarray将结构化数组的数据类型转换成numpy.record数据类型
>>> arr = np.array([("Tom",12,"Beijing"),("Anne",10,"Guangzhou"),("Kenty",15,"Shengzheng")],dtype=[("name","U5"),("age","i8"),("add ress","U5")]) >>> recarr = arr.view(dtype=np.dtype((np.record,arr.dtype)),type=np.recarray) >>> 复制代码
-
numpy.view()调用numpy.recarray方法,会自动转换成numpy.record 数据类型,可以直接省去dtype。
>>> recarr = arr.view(np.recarray) >>> 复制代码
注意,如果转换成非记录数组时,需要重置dtype和type。
>>> recarr = np.rec.array([("Tom",12,"Beijing"),("Anne",10,"Guangzhou"),("Kenty",15,"Shengzheng")],dtype=[("name","U5"),("age","i8" ),("address","U5")]) >>> arr = recarr.view(recarr.dtype.fields or recarr.dtype,np.ndarray) >>> type(arr) <class 'numpy.ndarray'> >>> type(recarr) <class 'numpy.recarray'> >>> 复制代码
3. 记录数组辅助函数
结构化数组转换成记录数组后,numpy 专门提供了numpy.lib.recfunctions模块中包含操作结构化数组的大量方法。
最初操作结构化的方法,是由John Hunter 为matplotlib 模块实现的。目前,这些方法已被重写和扩展。
例举常见的方法如下:
方法 | 作用 |
---|---|
numpy.lib.recfunctions.append_fields(base,name,data) | 将新字段添加到现有数组,name、data和 dtypes 是值,不是列表 |
numpy.lib.recfunctions.apply_along_fields(func,arr) | 应用函数func作为结构化数组字段 |
numpy.lib.recfunctions.assign_fields_by_name(dst,src) | 按字段名称将一个结构化数组中的值分配给另一个结构化数组 |
numpy.lib.recfunctions.drop_fields(base,drop_name) | 删除drop_name,并返回一个新结构化数组 |
numpy.lib.recfunctions.find_duplicates(a) | 查询结构化数组中重复项 |
numpy.lib.recfunctions.get_fieldstructure(adtype) | 将结构化数组转换成一个字典 |
总结
本期,我们主要对numpy 结构化数组转换成记录数组后,可以通过引用属性来访问结构化数组字段数据。
从记录数组转换成结构化数组时,我们需要重置dtype 和type.
以上是本期内容,欢迎大佬们点赞评论,下期见~