Numpy基础(二)索引与切片

1.基础索引与切片

1.1视图与副本

在numpy中的切片与索引,都是原数组的一个视图,也就是说,进行任何切片或者索引操作并不会产生一个新的数组,都是在原数组的基础上操作,这与其他语言的对象很像,而非一个基本类型。如下例:

arr = np.array([1, 2, 3, 4, 5])
view = arr[1:4]
view[0] = 20
print(arr)  # 输出: [ 1 20  3  4  5]

而拷贝需要显式的利用.copy函数完成。如下例子:

arr = np.array([1, 2, 3, 4, 5])
copy = arr[1:4].copy()
copy[0] = 20
print(arr)  # 输出: [1 2 3 4 5]

1.2索引与切片

一维数组的索引与切片和python原生的序列数组的使用是一样的,对于索引第 x x x位元素,则使用arr[ x − 1 x-1 x1](从0开始标号),而切片arr[ x x x, y y y]则表示为arr[ x x x]到arr[ y − 1 y-1 y1]的数据元素。
而对于更高维度的数组,可以通过arr[ x x x][ y y y][ z z z]······或者arr[ x x x y y y z z z,······]逐级索引,每增加一个索引值就是将原数组降低一个维度,如下例:

arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2]
arr2d[0][2]
arr2d[0, 2]

而对于切片也是类似的,与python原生的序列类型相似,困难点在于对于axis的理解,针对高维数据的理解可以看: 高维数组对象的理解,但是需要注意的是在日常使用中,多数数据类型为二维和三维数据,对于更高维度的索引与切片在本文以及后续文章中将不再详细说明,关注点放在二维与三维数据即可。
adarry的切片可以总结如下:对于任意维度,以start:stop:step的形式进行切割。当步长为1时,可以省略step,同样当从头开始到某处截止或者时从某处开始到结束可以省略start或者stop,如下所示:

arr2d
arr2d[:2]
arr2d[:2, 1:]
arr2d[1, :2]
arr2d[:2, 2]
arr2d[:, :1]

2.特殊索引

2.1布尔索引

要想理解布尔索引,得讲一个故事:首先构建一个name数组和data数组,假设在真实的世界中,name和data一一对应,,那么如何可以通过name数组筛选出对应的data数据?

names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
data = np.random.randn(7, 4)
names
data
#name:array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='<U4')
'''data:array([[-0.2047,  0.4789, -0.5194, -0.5557],
       [ 1.9658,  1.3934,  0.0929,  0.2817],
       [ 0.769 ,  1.2464,  1.0072, -1.2962],
       [ 0.275 ,  0.2289,  1.3529,  0.8864],
       [-2.0016, -0.3718,  1.669 , -0.4386],
       [-0.5397,  0.477 ,  3.2489, -1.0212],
       [-0.5771,  0.1241,  0.3026,  0.5238]])'''
names == 'Bob' 
#array([ True, False, False,  True, False, False, False])
data[names == 'Bob']
#array([[-0.2047,  0.4789, -0.5194, -0.5557],
#       [ 0.275 ,  0.2289,  1.3529,  0.8864]])

可以看到直接通过数组和值的比较操作就可以完成整体的布尔判断,返回的也是array,而对于数组的索引,也可以使用array来进行索引。
在进行布尔索引的过程中需要注意的是:1. 布尔数组的长度必须和数组某个轴方向的长度一致;2.与(&)或(|)3.若要取非可以使用!=表示不等,或者在条件前加~:

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

2.2 神奇索引

通过传递一个顺序列表或者数组可以直接完成符合特定顺序的子集,如下例:

arr = np.empty((8, 4))
for i in range(8):
    arr[i] = i
arr
'''
array([[0., 0., 0., 0.],
       [1., 1., 1., 1.],
       [2., 2., 2., 2.],
       [3., 3., 3., 3.],
       [4., 4., 4., 4.],
       [5., 5., 5., 5.],
       [6., 6., 6., 6.],
       [7., 7., 7., 7.]])
'''
arr[[4, 3, 0, 6]]
'''
array([[4., 4., 4., 4.],
       [3., 3., 3., 3.],
       [0., 0., 0., 0.],
       [6., 6., 6., 6.]])
'''
arr[[-3, -5, -7]]#也可以是负数,从后向前
'''
array([[5., 5., 5., 5.],
       [3., 3., 3., 3.],
       [1., 1., 1., 1.]])
'''
arr = np.arange(32).reshape((8, 4))
arr
arr[[1, 5, 7, 2], [0, 3, 1, 2]]
'''
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23],
       [24, 25, 26, 27],
       [28, 29, 30, 31]])
array([ 4, 23, 29, 10])
'''
arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
'''
array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])
'''

需要注意的是,和基础切片与索引极为相似,但是少了一层中括号,即基础切片与索引中是arr[ x x x y y y z z z,······],而神奇索引是arr[[ x x x y y y z z z,······]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值