2025年4月1日 星期二 乙巳(蛇)年 正月初二 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

Numpy布尔索引掩码操作详解

时间:03-29来源:作者:点击数:82

本节我们讲解 Numpy 数组的布尔索引操作,大家对于这一概念很可能会无感,通过本节知识的介绍,你会认识到 Numpy 数组的与众不同的。Numpy 数组布尔索引也可以叫做掩码操作,即通过一组布尔值序列,对 Numpy 数组进行取值操作,下面就正式进入本节的主要内容。

1. 简单的数组掩码操作

布尔值即 True 或 False 使用它们两者进行索引可以使 Numpy 数组呈现出我们想要的数据,我们先看一个简单的示例:

  • In [1]: import numpy as np
  • In [2]: data=np.arange(1,11)
  • #创建mask掩码布尔值列表
  • In [3]: mask=[True,False,True,False,True,False,True,False,True,False]
  • #使用布尔值对数组data进行索引
  • In [4]: data[mask]
  • #输出只有奇数的数组
  • Out[4]: array([1, 3, 5, 7, 9])

通过上面的代码,你应该对布尔值索引有了一个基本的认识。这种使用 mask 布尔值序列对数组进行取值的操作,称之为掩码,即掩盖掉不想显示的数据。下面我们讲一些实际的应用场景。

2. 数组掩码实际应用

假设现在有一组班级姓名的数组,并且还有一组成绩表,成绩表我们可以随机生成一组数据,如下所示:

  • In [1]: import numpy as np
  • In [2]: data=np.arange(1,11)
  • In [3]: mask=[True,False,True,False,True,False,True,False,True,False]
  • In [4]: data[mask]
  • Out[4]: array([1, 3, 5, 7, 9])
  • In [5]: import numpy as np
  • #名字数组
  • In [6]: names=np.array(['xm','ls','cd','ra','xm','lz'])
  • #随机生成6行4列的成绩数组并和姓名一一对应
  • In [7]: data=np.random.randn(6,4)
  • In [8]: data
  • Out[8]:
  • array([[ 0.11862692, 0.43370356, 0.24572782, 0.12563666],
  • [-0.66938338, -0.27592135, 0.27299139, -0.62841077],
  • [-0.49116108, -1.34173789, 1.71092549, 0.97037571],
  • [ 0.79156476, -0.33761401, 0.15094182, 0.59195507],
  • [-0.10606347, 0.00604084, -0.3119981 , -0.82903705],
  • [ 1.2775524 , -0.76599632, -1.41684961, 0.27957322]])
  • In [9]: names
  • Out[9]: array(['xm', 'ls', 'cd', 'ra', 'xm', 'lz'], dtype='<U2')

我们假设每个人名都和 data 数组的一行数据相对应,如果此时我们想要根据名字筛选出我们想要的成绩应该怎么做呢?我们知道 True 和 False 可以用来判断一个 if 表达式的条件是否成立,若成立则返回 True,否则就返回 False,所以在此处依然使用这种思想来考虑。

我们使用数学上的比较运算符就可以得到想要的结果,如下所示:

  • In [1]: import numpy as np
  • In [2]: names=np.array(['xm','ls','cd','ra','xm','lz'])
  • In [3]: data=np.random.randn(6,4)
  • In [4]: names
  • Out[4]: array(['xm', 'ls', 'cd', 'ra', 'xm', 'lz'], dtype='<U2')
  • In [5]: data
  • Out[5]:
  • array([[ 1.27893324, -0.2869719 , 1.53727143, 0.92759443],
  • [-1.34825698, 0.61118769, 0.09381353, -0.25670181],
  • [ 1.23828121, -0.60258588, -1.29633343, -0.79827614],
  • [-0.69281436, 0.35496869, -1.18819669, -1.06783884],
  • [-0.63522862, -0.46742291, 1.29312452, -1.83039843],
  • [ 1.0572994 , 1.55526538, 0.46449384, -0.2587228 ]])
  • #使names数组等于xm会生成布尔序列数组
  • In [6]: names=="xm"
  • #为xm的位置显示为True
  • Out[6]: array([ True, False, False, False, True, False])
  • #对data数组进行掩码操作
  • In [7]: data[names=="xm"]
  • #输入结果为xm对应的行数
  • Out[7]:
  • array([[ 1.27893324, -0.2869719 , 1.53727143, 0.92759443],
  • [-0.63522862, -0.46742291, 1.29312452, -1.83039843]])

这里有一点需要大家注意,布尔值数组长度必须和数组索引长度一致。继续上面示例,我们还可以使用如下的方式,父获取的数组结果进一步操作:

  • In [8]: data[names=="xm"]
  • Out[8]:
  • array([[ 1.27893324, -0.2869719 , 1.53727143, 0.92759443],
  • [-0.63522862, -0.46742291, 1.29312452, -1.83039843]])
  • #前面的位置代表选择行,后面表示选择列
  • In [9]: data[names=="xm",3]
  • Out[9]: array([ 0.92759443, -1.83039843])
  • In [10]: data[names=="xm",-2]
  • Out[10]: array([1.53727143, 1.29312452])
  • In [11]: data[names=="xm",1:]
  • Out[11]:
  • array([[-0.2869719 , 1.53727143, 0.92759443],
  • [-0.46742291, 1.29312452, -1.83039843]])

data[names=="xm",1:] 表示 data 对应names=='xm' 的行,列取值不包含第一列以外的所有列。

3. 掩码的其他使用方法

1) 使用 | 和 &生成布尔值索引

理解了上面的使用方法后,我们再来看看其他使用方法,我们也可以使用逻辑运算符号 | 和 & 来进行布尔值索引,它们分别代表着 or 和 and,在布尔值中需要使用符号来代替关键字,如下所示:

  • In [19]: mask=(names=="xm")|(names=="ls")
  • In [20]: mask
  • Out[20]: array([ True, True, False, False, True, False])
  • In [21]: mask=(names=="xm")&(names=="ls")
  • In [22]: mask
  • Out[22]: array([False, False, False, False, False, False])

2) 使用 !=和~进行掩码操作

使用不相等和取反也可以进行掩码操作,如下所示,它们最终的结果是一样的:

  • In [12]: names!="xm"
  • Out[12]: array([False, True, True, True, False, True])
  • In [13]: data[names!="xm"]
  • Out[13]:
  • array([[-1.34825698, 0.61118769, 0.09381353, -0.25670181],
  • [ 1.23828121, -0.60258588, -1.29633343, -0.79827614],
  • [-0.69281436, 0.35496869, -1.18819669, -1.06783884],
  • [ 1.0572994 , 1.55526538, 0.46449384, -0.2587228 ]])
  • In [14]: data[~(names=="xm")]
  • Out[14]:
  • array([[-1.34825698, 0.61118769, 0.09381353, -0.25670181],
  • [ 1.23828121, -0.60258588, -1.29633343, -0.79827614],
  • [-0.69281436, 0.35496869, -1.18819669, -1.06783884],
  • [ 1.0572994 , 1.55526538, 0.46449384, -0.2587228 ]])

3) 使用数学比较号生成布尔值

我们可以使用数学上的比较符号对数组值进行判断,进而操作数组中数值,比如重新赋值等:

  • In [23]: data<0
  • #data<0生成布尔值数组
  • Out[23]:
  • array([[False, True, False, False],
  • [ True, False, False, True],
  • [False, True, True, True],
  • [ True, False, True, True],
  • [ True, True, False, True],
  • [False, False, False, True]])
  • In [24]: data[data<0]=0
  • #对于满足条件的数值进行修改去掉负值
  • In [25]: data
  • Out[25]:
  • array([[1.27893324, 0. , 1.53727143, 0.92759443],
  • [0. , 0.61118769, 0.09381353, 0. ],
  • [1.23828121, 0. , 0. , 0. ],
  • [0. , 0.35496869, 0. , 0. ],
  • [0. , 0. , 1.29312452, 0. ],
  • [1.0572994 , 1.55526538, 0.46449384, 0. ]])
  • In [26]: data[names!='lz']=7
  • #对于满足条件的数据进行修改
  • In [27]: data
  • Out[27]:
  • array([[7. , 7. , 7. , 7. ],
  • [7. , 7. , 7. , 7. ],
  • [7. , 7. , 7. , 7. ],
  • [7. , 7. , 7. , 7. ],
  • [7. , 7. , 7. , 7. ],
  • [1.0572994 , 1.55526538, 0.46449384, 0. ]])

通过上面的示例,我们可以看出 Numpy 数组强大功能以及它的灵活性,对于上述操作方法需要大家实际去练习然后再掌握它们。注意当我们再使用布尔值索引选择数据时,生成的是数据的拷贝,即不会影响到原数组数据。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门