NumPy - 高级索引
如果一个ndarray
是非元组序列,数据类型为整数或布尔值的ndarray
,或者至少一个元素为序列对象的元组,我们就能够用它来索引ndarray
。高级索引始终返回数据的副本。 与此相反,切片只提供了一个视图。
有两种类型的高级索引:整数和布尔值。
整数索引
这种方式使用 N 维索引来获取数组中任意元素。 索引的每个整数数组表示该维度的下标值。 例如[[1, 2], [3, 4]] 表示要取a[1][3], a[2][4] 的两个元素组成一个新的对象。整数索引提供了一种更强大的源数据到新数据的生成的对应关系,而不是像切片一样只能切出连续的块。
1,指定任意下标的元素
例如要取一个原有一维数组2、17、6、88、2、40索引的数。
import numpy as np
x = np.arange(100)
a = x[[2, 17, 6, 88, 2, 40]]
print(a)
输出,这里的索引和值是一样的,因此很容易验证对应关系。使用中的源数据可能是任意的。
[ 2 17 6 88 2 40]
要实现复杂的操作更是如此。例如要取一个有100个元素的数组中,索引是2的幂的元素
index = [x for x in np.logspace(1, 10, num=10, base=2, dtype=int) if x < 100]
a = np.arange(100)
print(a[index])
[ 2 4 8 16 32 64]
2,指定 N 维数组中的元素
以下示例获取了ndarray
对象中指定行指定列的元素。 在这种指定模式中,行索引包含所有行号,列索引指定要选择的元素。
import numpy as np
x = np.array([[1, 2],
[3, 4],
[5, 6]])
y = x[[0,1,2],
[0,1,0]]
print(y)
[0, 1, 2] 是第一维的索引,是用于指定行号; [0, 1, 0]是用于指定第二维的,用于指定列号。更多的维度以此类推。 输出如下:
[1 4 5]
该结果包括数组中(0,0)
,(1,1)
和(2,0)
位置处的元素。
下面的示例获取了 4X3 数组中的每个角处的元素。 行索引是[0,0]
和[3,3]
,而列索引是[0,2]
和[0,2]
。
示例 2
import numpy as np
x = np.array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
print('我们的数组是:')
print(x, '\n')
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
print('这个数组的每个角处的元素是:')
print(y)
输出如下:
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
这个数组的每个角处的元素是:
[[ 0 2]
[ 9 11]]
返回的结果是包含每个角元素的ndarray
对象。
注意的问题,list 和 numpy.array是不一样。在取数据的内容也不是等价的。
没有找到其中的规律,以后再看。
import numpy as np
x = np.array([[1, 2],
[3, 4],
[5, 6]])
list = [[[[0,2],[1,2]]],
[[0,1],[1,0]]]
array = np.array(list)
print(x[list], '\n\n')// list是以前几个维度和adarray对应的。得到的是内部的重新组合。
print(x[array], '\n\n') // ndarray作为索引时,是以行为单位的。索引中的每个数组代表源数组中的一行。然后根据外部结构从新组合。
混合使用
高级和基本索引可以通过使用切片:
或省略号...
与索引数组组合。 以下示例使用slice
作为列索引和高级索引。 当切片用于两者时,结果是相同的。 但高级索引会导致复制,并且可能有不同的内存布局。
示例 3
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print('我们的数组是:')
print(x)
print('\n')
# 切片
z = x[1:4,1:3]
print('切片之后,我们的数组变为:')
print(z)
print('\n')
# 对列使用高级索引
y = x[1:4,[1,2]]
print '对列使用高级索引来切片:'
print y
输出如下:
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
切片之后,我们的数组变为:
[[ 4 5]
[ 7 8]
[10 11]]
对列使用高级索引来切片:
[[ 4 5]
[ 7 8]
[10 11]]
布尔索引
当结果对象是布尔运算(例如比较运算符)的结果时,将使用此类型的高级索引。
示例 1
这个例子中,大于 5 的元素会作为布尔索引的结果返回。
import numpy as np
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print '我们的数组是:'
print x
print '\n'
# 现在我们会打印出大于 5 的元素
print '大于 5 的元素是:'
print x[x > 5]
输出如下:
我们的数组是:
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
大于 5 的元素是:
[ 6 7 8 9 10 11]
示例 2
这个例子使用了~
(取补运算符)来过滤NaN
。
import numpy as np
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print a[~np.isnan(a)]
输出如下:
[ 1. 2. 3. 4. 5.]
示例 3
以下示例显示如何从数组中过滤掉非复数元素。
import numpy as np
a = np.array([1, 2+6j, 5, 3.5+5j])
print a[np.iscomplex(a)]
输出如下:
[2.0+6.j 3.5+5.j]