得益于模块功能的强大,numpy的索引方式玩得很花,索引也分为常规索引和高级索引,花式索引。
numpy的索引和切片逻辑与list十分相似,基本都以index为基。
之前提到结构化数组通过"name"的方式索引,有点像pandas的列名索引,这里先不多提,整体也好理解。
你可能猜到了,numpy的索引同样从零开始。
先把索引操作放一边,尝试理解它的逻辑:
虽然探究numpy的源代码并不容易,我们试着把概念抽象出来,换个视角看看。
我们把array对象可以看作线、面、体的嵌套形结构,索引与结构一一对应。就像这样:
数组结构与索引的关系.png这种数组结构与索引的对应关系非常鲜明,让我们看清索引是怎样一步步定位到值的。再结合几个例子看一下:
import numpy as np
datas = [1,2,3,4,5,6,7,8,9,10,11,12]
array_1d = np.array(datas) # 线
array_2d = np.array(datas).reshape((4,3)) # 面
array_3d = np.array(datas).reshape((2,3,2)) # 体
print(array_1d)
print(array_1d[1:3]) # 还是左闭右开的切片 ****** 第2个到第4个(不含)
# 运行结果:
[ 1 2 3 4 5 6 7 8 9 10 11 12] # 原数组
[2 3] # 结果(切片)
print(array_2d)
print(array_2d[1]) # 取整行 ****** 第2行
# 运行结果:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]] # 原数组
[4 5 6] # 结果(取整行)
print(array_3d)
print(array_3d[1, 0, 0]) # 取值 ****** 第2个,第1行,第1个
print(array_3d[1, 2, :]) # 取行的某段 ****** 第2个,第3行,全部切片
print(array_3d[1, 1]) # 取整行 ****** 第2个,第2行
# 运行结果:
[[[ 1 2]
[ 3 4]
[ 5 6]]
[[ 7 8]
[ 9 10]
[11 12]]] # 原数组
7 # 结果(取值)
[11 12] # 结果(取行的某段)
[ 9 10] # 结果(取整行)
理解到这里,恭喜你已经掌握了索引、切片、多维切片、高级索引的大部分知识点。再看几个例子补充完剩下的:
import numpy as np
datas = [1,2,3,4,5,6,7,8,9,10,11,12]
array_1d = np.array(datas) # 线
array_2d = np.array(datas).reshape((4,3)) # 面
print(array_1d)
print(array_1d[:9:2]) # 切片操作,(起:止:步长)
print('* '*20)
print(array_2d)
print(array_2d[[1,3],[0,2]]) # 整数数组索引。前后分别是行/列,索引一一对应,相当于(1,0)和(3,2)的意思
print(array_2d[array_2d > 5]) # 布尔索引。找到True的位置对应的值
print(array_2d[[1,2,3]]) # 花式索引。取第2行,第3行,第4行(要用中括号包住,否则意思就变成了在2d数组里找体、行、列)
# 运行结果:
[ 1 2 3 4 5 6 7 8 9 10 11 12]
[1 3 5 7 9]
* * * * * * * * * * * * * * * * * * * *
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[ 4 12]
[ 6 7 8 9 10 11 12]
[[ 4 5 6]
[ 7 8 9]
[10 11 12]]
numpy的索引就到这里。
下篇内容会介绍numpy里的广播机制。
等理解完前面这些知识点,后面的进度就会快一些。
网友评论