python numpy 结构化数组之记录数组

image.png

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

前言

python numpy 提供多维数组对象、数组快速操作的方法的科学计算基础库,其包名普通数组和结构化数组。我们前面已经学习了结构化数组相关知识如:

image.png

我们都知道,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.

以上是本期内容,欢迎大佬们点赞评论,下期见~

猜你喜欢

转载自juejin.im/post/7062678582035759134
今日推荐