Python numpy之结构化数组赋值

1,131 阅读3分钟

image.png

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

前言

众所周知,Python list具有切片索引的功能。numpy 数组同样是使用 Python 标准的x[obj] 对象来实现的。

numpy之索引中,我们可以知道numpy 数组索引可以分为基本索引、高级索引等

  • 基本索引使用的是单元素索引进行的,结果返回的是副本
  • 基本切片按照start:end:step格式进行,结构返回的是视图
  • 高级索引主要分为整数数组索引、布尔索引及花式索引
  • 高级索引返回的结果是副本

image.png

我们前面也学习了的numpy之结构化数组中可以知道,结构化数组是由一系列的数据类型命名的字段组成组成的,其数据类型是字节序列(itemsize)。每一个字段由name、datatype和offset组成。

numpy 对于普通的数组,都支持索引切片操作,哪结构化数组是否支持索引呢?

答案是肯定的,numpy 结构化数组同样支持索引赋值操作。

本期,我们先学习numpy 结构化数组赋值的相关操作吧,Let's go~~

1. 结构化数组赋值

对于在Python内置数据类型如list、tuple等,我们可以通过索引下标等操作进行赋值即可

同理,在 numpy 结构化数组赋值也有三种方法:来自元组赋值、标量赋值、来之其他结构化数组赋值。

image.png

2. 来自元组赋值

numpy 使用python tuple 方式将数据值赋值给结构化数组是最简单的方法

  • 赋值元组数据值要与数组中字段数的元组长度一致

  • 赋值的过程中,会触发numpy 的广播规则

  • 元组的数据赋值给数组字段顺序从左到右,且内存空间是连续的

    >>> stu_type = np.dtype({"name":("S6",0,"nickname"),"age":("i8",1)})
    >>> stu_list = np.array([("Tom",12),("Anne",10),stu_type])
    >>> stu_list[0] = ("Tony",15)
    >>> stu_list
    array([('Tony', 15), ('Anne', 10),
           dtype({'names':['name','age'], 'formats':['S6','<i8'], 'offsets':[0,1], 'titles':['nickname',None], 'itemsize':9})],
          dtype=object)
    >>>
    

我们将元组列表("Tony",15) 赋值给结构化数组 stu_list[0]这个字段,可以清楚看到stu_list[0] 原来数据("Tom",12)更新为("Tony",15)

3.标量赋值

numpy 可以使用标量的方法将数组中的值赋值给所有字段。

  • 使用标量进行赋值时,当赋值的形状与原始数组不一致时,系统会报Value Error

    >>> stu_list
    array([('Tony', 15), ('Anne', 10),
           dtype({'names':['name','age'], 'formats':['S6','<i8'], 'offsets':[0,1], 'titles':['nickname',None], 'itemsize':9})],
          dtype=object)
    >>> stu_list[:] = "Juejin"
    >>> stu_list
    array(['Juejin', 'Juejin', 'Juejin'], dtype=object)
    >>>
    
    

    结构化数组也可以给非结构化数组进行赋值,要求结构化数组dtype只有一个字段

    如果存在多个dtype的结构化数组赋值时,系统会报TypeError

    >>> y1 = np.zeros(2,dtype=[('A','i8')])
    >>> y2 = np.zeros(2,dtype=[('A',"i8"),("B","i4")])
    >>> y = np.zeros(2,dtype="i4")
    >>> y[:]=y2
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Cannot cast scalar from dtype([('A', '<i8'), ('B', '<i4')]) to dtype('int32') according to the rule 'unsafe'
    >>>
    
    

4. 来自其他结构化数组赋值

将两个具有相同数量字段的结构化数组进行赋值,numpy 内部按照从左到右的顺序,从第一个字段赋值给原数组的第一个字段值,第2个新字段的值赋值给原数组第2个字段,后面依次类推。

  • 两个结构化数组字段数量要保持相同
  • 未包含任何字段中的原数组字节不受影响
```python
>>> x = np.array([("Thu",3),("Wen",4),("Fri",5)],dtype=[("name","U5"),("num","i8")])
>>> x1 = np.array([("Mon",1),("Sun",7),("Fri",5)],dtype=[("name","U5"),("num","i8")])
>>> x1[:] = x
>>> x1
array([('Thu', 3), ('Wen', 4), ('Fri', 5)],
      dtype=[('name', '<U5'), ('num', '<i8')])
>>>
```

总结

本期,我们numpy 结构化数组赋值的三种方法进行基本的了解和学习。

赋值使用的来自元组数据对于结构化数组赋值来说是最简单方便的,要求元组的长度要与数组字段数保持一致,绝对不大于,否则系统会报ValueError。

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