numpy数组的索引遵循python中x[obj]模式,也就是通过下标来索引对应位置的元素。在numpy数组索引中,以下问题需要主要: 1)对于单个元素索引,索引从0开始,也就是x[0]是第一个元素,x[n-1]对应第n个元素,最后一个元素为x[d-1],d为该维度的大小。 2)对于多个元素索引,索引也是从0开始,但是不包含最后一个索引值对应的元素,属于前闭后开区间索引,x[2,5]表示x的第3,4,5三个元素。 3)对于多个维度索引,维度之间用,(逗号隔开),例如X[1:3,4:6] 。 4)支持切片索引。 5)支持布尔值索引。 6)支持负数索引,-a代表d-a位置,d为该维度大小,例如-1代表最后一个元素的索引。 7)支持空位置,例如 x[:3]代表3前面所有的元素,但是不包括3 x[2:]表示2后面所有元素,并包含2。
import numpy as np
a = np.arange(24)
a.shape=(2,3,4)
print('a 数据为:',a)
# 单元素索引,
b = a[0,1,3]
print('b is:',b)
# 多元素索引
c = a[:,:2,1:3]
print('c is:', c)
d = a[ ...,:2,1:3]
print('d is:',d)
输出:
a 数据为: [[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
b is: 7
c is: [[[ 1 2]
[ 5 6]]
[[13 14]
[17 18]]]
d is: [[[ 1 2]
[ 5 6]]
[[13 14]
[17 18]]]
notes: …和: 都可以表示该维度的所有元素
通过负数索引,需要注意以下问题:(注意看c的区别) 1)冒号(:)后面的值实际位置一定要大于冒号前的位置,否则返回为空,也就是不能倒序索引(有其他办法解决) 2)要想倒序索引,则切片顺序要改为-1,例如:x[-1:1:-1]
import numpy as np
a = np.arange(24)
a.shape=(4,6)
print('a 数据为:',a)
b = a[-2,-3]
print('b is:',b)
c1 = a[0:-2,2]
print('c1 is',c1)
c2 = a[-2:0,2]
print('c2 is',c2)
c3 = a[-4:-2,2]
print('c3 is',c3)
d = a[-1:0:-2,-2:0:-2]
print('d is:', d)
输出:
a 数据为: [[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
b is: 15
c1 is [2 8]
c2 is []
c3 is [2 8]
d is: [[22 20]
[10 8]]
综上:在基础 索引中都是采用的python切片形式:x[start:stop:step] ,结合负数索引,可以从后向前,当step为负数时,则为倒序索引。
import numpy as np
a = np.arange(9)
a.shape=(3,3)
print('a 数据为:',a)
b = a[2,:]
print('b 的 shape is:',b.shape)
c = a[2:3,:]
print('c的shape is',c.shape)
输出: a 数据为: [[0 1 2] [3 4 5] [6 7 8]] b 的 shape is: (3,) c的shape is (1, 3)
a 数据为: [[0 1 2]
[3 4 5]
[6 7 8]]
b 的 shape is: (3,)
c的shape is (1, 3)
注意b和c的区别,当该维度是单个数时,会丢失该维度,所以b变为1维了,如果要保持维度不变,一定要采取c的索引形式,哪怕只有只需要该维度的一个元素。
基础所以通过切片的方式索引,而高级索引每一个维度上的索引下标可以为矩阵。高级索引有两种方式:整数索引和bool值索引
bool索引的本质就相当于mask,索引数组的维度大小与原数组一样,返回索引数组中为Ture的位置对应的值,并压平为一维数组。
import numpy as np
a = np.arange(9)
a.shape=(3,3)
print('a 数据为:',a)
ind = a > 5
print('ind is :', ind)
b = a[ind]
print('b is:',b)
print( 'shape of b is:',b.shape)
a[ind] = 1
print(a)
a[ind] = [1,2,3]
print(a)
输出:
a 数据为: [[0 1 2]
[3 4 5]
[6 7 8]]
ind is : [[False False False]
[False False False]
[ True True True]]
b is: [6 7 8]
shape of b is: (3,)
[[0 1 2]
[3 4 5]
[1 1 1]]
[[0 1 2]
[3 4 5]
[1 2 3]]
同样,也可以通过bool索引去对数组赋值。
整数索引是说可以用数组去索引,规则符合numpy的boadcast规则,也就是每一维度的索引数组会相互组合。
import numpy as np
a = np.arange(16)
a.shape=(4,4)
print('a 数据为:',a)
ind = np.array([1,3])
print(a[ind])
输出:
a 数据为: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
[[[ 4 5 6 7]
[12 13 14 15]]]
因为只有第一维度给出了索引数组,所以第二维度完全保留,因而结果返回的是第二行和第四行。
import numpy as np
a = np.arange(16)
a.shape=(4,4)
print('a 数据为:',a)
row = np.array([[1,3],[3,1]])
col = np.array([[0,2],[2,1]])
print('index value is :', a[row,col])
输出:
a 数据为: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
index value is : [[ 4 14]
[14 5]]
采用boardcast方式,两个维度的索引矩阵对饮元素组合:(1,0),(3,2),(3,2),(1,1),故返回该结果。且返回结果的数组维度不变。 这种方式必须保证:索引数组的维度以及每一维度的大小一样,才能应用boardcast规则。
ix_函数是用来扩充维度,因为在整数索引中要保证每个维度的索引数组的维度一样,则可以直接用ix_函数来构建索引函数
import numpy as np
a = np.arange(16)
a.shape=(4,4)
print('a 数据为:',a)
row = np.array([1,3])
col = np.array([0,2])
print('index value is :', a[np.ix_(row),np.ix_(col)])
输出:
a 数据为: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
index value is : [[ 4 14]]
组合应该为(1,0),(3,2)位置的元素,返回两个值。可以发现,重复元素不返回。