Numpy 切片(slicing)和python的省略(ellipsis)

上篇文章中介绍了一些numpy的基本用法,其中使用numpy的对图像进行灰度处理的时候,用到了pic[…,:3],这个方法,代码如下:

1
2
3
4
5
6
# 默认灰度
weights = array([[ 0.2989, 0.587 , 0.114 ]])
gray = np.dot(pic[...,:3], weights)
#得到 (R*0.2989+ G*0.5870+ B*0.1140)灰阶值,图像的二维尺寸不变,而减为单通道
plt(gray, cmap='Greys') # 注意要以灰度形式画出
plt.show()

这里面的省略号…含义是什么呢?这篇文章做个简单的介绍。

首先我们定义一个数组

1
2
3
4
5
6
7
8
9
10
11
12
import numpy as np
a=np.arange(24).reshape(2,3,4)
a.shape
#(2, 3, 4)
print(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]]]

索引

多维数组中,如果我们要访问里面的单个元素只要指定其中的索引值就好了,python中对于索引有他自己的独特简化写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
a[1][2][3]
#输出 23,也就是最后一个数字,因为索引是0开始的,也就是最后一个元素 23
a[1,2,3]
#输出也是23也就是上面的简化写法
a[0][1][:2] #[0,1,:2]
#array([4, 5])
#第1行第2列前两个元素
a[0][1][1:] #[0,1,1:]
#array([5, 6, 7])
#第1行第2列第2个元素以后的所有元素
a[0][1][1:2] #[0,1,1:2]
#array([5])
#第1行第2列第2个到第3个元素,前面包含,后面不包含

对于列使用上会有一些特殊的要求

1
2
3
4
5
6
7
8
9
10
a[0][:1]
#array([[0, 1, 2, 3]])
#第1行,第1列(包含)的数据
a[0][:1][1]
#报错 IndexError: index 1 is out of bounds for axis 0 with size 1
a[0,:1,1]
#这样写就没问题,返回array([1])
a[0,:2,1:]
#array([[1, 2, 3],
# [5, 6, 7]])

下面一个操作符号就是两个双引号 :: 中间隔地选定元素

1
2
3
4
5
6
a[0,1,::1]
#array([4, 5, 6, 7])
#所有元素
a[0,1,::2]
#array([4, 6])
#间隔选择,中间跳过了一个元素

省略

下面真正的主题该出场了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a[...] #这个选择所有的元素,与a一样
a[1,...] # 等同于a[1]一样
a[...,1]
#array([[ 1, 5, 9],
# [13, 17, 21]])
# 前面的元素不变,选择最后一维的第2个元素,组成新的数组
a[1,...,1]
# array([13, 17, 21])
#因为就三维所以没有效果,如果维度再多一些就好理解了
b=np.arange(120).reshape(2,3,4,5)
b[1,...,1]
#array([[ 61, 66, 71, 76],
# [ 81, 86, 91, 96],
# [101, 106, 111, 116]])
#这样就很好理解了

参考文档

http://old-blog.xlzd.me/2016/05/20/ellipsis

http://blog.csdn.net/mydear_11000/article/details/73089435

https://www.cnblogs.com/jpld/p/4970148.html