python布尔系列_python数据分析类库系列-Numpy之布尔型索引

我们了解了如何使用索引进行切片以及选择 ndarray 元素。当我们知道要选择的元素的确切索引时,这些方法很有用。但是,在很多情况下,我们不知道要选择的元素的索引。例如,假设有一个 10,000 x 10,000 ndarray,其中包含从 1 到 15,000 的随机整数,我们只想选择小于 20 的整数。这时候就要用到布尔型索引。

来看这样一个例子,假设我们有一个用于存储数据的数组以及一个存储姓名的数组(含有重复项)。在这里,我将使用numpy.random中的randn函数生成一些正态分布的随机数据:

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])

data =np.random.randn(7,4)

data

out

array([[-0.53447574, 0.44543995, 0.20598584, 1.08783591],

[-0.77863291, 0.19012144, -0.57628278, 2.21230602],

[-1.94785822, 1.75829325, 0.76416317, -0.26749686],

[ 1.55128542, -0.48229173, -0.10775036, 1.82210628],

[-0.75344013, 1.49328631, 0.19576227, -1.37773471],

[-0.28998065, -0.54219643, 0.44587161, -1.17333163],

[ 2.28372601, 0.9102604 , -0.15811983, 1.16763758]])

假设每个名字都对应data数组中的一行,而我们想要选出对应于名字"Bob"的所有行。跟算术运算一样,数组的比较运算(如==)也是矢量化的。因此,对names和字符串"Bob"的比较运算将会产生一个布尔型数组:

names == "Bob"

out

array([ True, False, False, True, False, False, False])

********************************************************

data[names =='Bob'] #True为选择,False为不选择

out

array([[7., 7., 7., 7.],

[7., 7., 7., 7.]])

布尔型数组的长度必须跟被索引的轴长度一致。此外,还可以将布尔型数组跟切片、整数(或整数序列,稍后将对此进行详细讲解)混合使用:

data[names == 'Bob']

out

array([[-1.33599022, 0.04700321, 0.98537189, 0.33183721],

[-0.2225323 , 0.10320653, 1.24636372, -0.38496333]])注意:如果布尔型数组的长度不对,布尔型选择就会出错,因此一定要小心。

下面的例子,我选取了names == 'Bob'的行,并索引了列:

data[names == 'Bob', 2:]

out

array([[ 0.98537189, 0.33183721],

[ 1.24636372, -0.38496333]])

********************************************************

data[names == 'Bob', 3]

out

要选择除"Bob"以外的其他值,既可以使用不等于符号(!=),也可以通过~对条件进行否定:

names != "Bob"

out

array([False, True, True, False, True, True, True])

********************************************************

data[~(names == 'Bob')]

out

array([[ 0.04813526, 0.481971 , -0.23318465, -0.08770203],

[ 2.39572745, -0.03834795, -0.49294046, -0.76124253],

[-0.30962763, 0.3454903 , 0.30120547, 0.82999187],

[-1.46354427, -1.00491798, 0.4574028 , 1.26923957],

[ 0.46142634, 1.55466835, -0.54772161, -0.65769753]])

~操作符用来反转条件很好用

cond = names == 'Bob'

data[~cond]

out

array([[ 0.04813526, 0.481971 , -0.23318465, -0.08770203],

[ 2.39572745, -0.03834795, -0.49294046, -0.76124253],

[-0.30962763, 0.3454903 , 0.30120547, 0.82999187],

[-1.46354427, -1.00491798, 0.4574028 , 1.26923957],

[ 0.46142634, 1.55466835, -0.54772161, -0.65769753]])

选取这三个名字中的两个需要组合应用多个布尔条件,使用&(和)、|(或)之类的布尔算术运算符即可:

mask = (names == "Bob") | (names == "Will" )

mask

out

array([ True, False, True, True, True, False, False])

********************************************************

data[mask]

out

array([[-1.33599022, 0.04700321, 0.98537189, 0.33183721],

[ 2.39572745, -0.03834795, -0.49294046, -0.76124253],

[-0.2225323 , 0.10320653, 1.24636372, -0.38496333],

[-0.30962763, 0.3454903 , 0.30120547, 0.82999187]])

通过布尔型索引选取数组中的数据,将总是创建数据的副本,即使返回一模一样的数组也是如此。注意:Python关键字and和or在布尔型数组中无效。要使用&与|。

通过布尔型数组设置值是一种经常用到的手段。为了将data中的所有负值都设置为0,我们只需:

data[data < 0] = 0

data

out

array([[0. , 0.04700321, 0.98537189, 0.33183721],

[0.04813526, 0.481971 , 0. , 0. ],

[2.39572745, 0. , 0. , 0. ],

[0. , 0.10320653, 1.24636372, 0. ],

[0. , 0.3454903 , 0.30120547, 0.82999187],

[0. , 0. , 0.4574028 , 1.26923957],

[0.46142634, 1.55466835, 0. , 0. ]])

通过一维布尔数组设置整行或列的值也很简单:

data[names != 'Joe'] = 7

data

out

array([[7. , 7. , 7. , 7. ],

[0.04813526, 0.481971 , 0. , 0. ],

[7. , 7. , 7. , 7. ],

[7. , 7. , 7. , 7. ],

[7. , 7. , 7. , 7. ],

[0. , 0. , 0.4574028 , 1.26923957],

[0.46142634, 1.55466835, 0. , 0. ]])

后面会看到,这类二维数据的操作也可以用pandas方便的来做。

下期我们将分享Numpy的花式索引,如果喜欢请点赞收藏,您的支持是我最大的动力,谢谢大家,共同进步。扫描二维码关注全部内容


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部