前言:
本文根据本人自己的学习成果总结的,内容难免产生纰漏,如有错误,望各位路过大佬指出。
建议按顺序食用本文,效果更佳。
文内例子均以二维数组为例。
本文主要包含numpy.ndarray数组的多种切片方法。在阅读本文前,请思考下面的问题:
Q:假如给你一个棋盘格式方形蛋糕,怎么切都可以,但刀必须落在棋盘格线上,你有几种切法?
单行切片:
按照上面问题的思维,切片无非是横切或是竖切。简单切片类似于:切一刀,拎出一行一维数组。
c = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[3, 5, 6, 0],
[8, 9, 5, 6]])
c1 = c[1]
print("切片多维列表中的某一行:", c1)
'''方括号内数字可随意变换'''
# 切片多维列表中的某一行: [5 6 7 8]
产生新的问题:如果我想要输出多行怎么实现?
尝试1: 如果我想输出1~3行(注意,这里行数计算从0开始),是否可以写成如下代码?
c1 = c[1, 3]
print("切片多维列表中的某几行:", c1)
# 切片多维列表中的某几行: 8
不可行,为什么?
因为方括号内两个用逗号间隔的数字分别代表行和列。当我只输入一个数字时,默认该数字为行。
单列切片:
那如果我想输出某一列呢?
使用...,(三个半角点号,加一个半角逗号)占位,后加想要输出的列数即可:
c1 = c[..., 3]
print("切片多维列表中的某一列:", c1)
'''
c = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[3, 5, 6, 0],
[8, 9, 5, 6]])
'''
# 切片多维列表中的某一列: [4 8 0 6]
尝试2:用切片
c2 = c[1:3]
print("切片:", c2)
# 切片: [[5 6 7 8]
# [3 5 6 0]]
注:输出不包含第三行。
按照尝试1中的发散思维,我们可以尝试“切片多列”,“行列全切”
多行多列切片:
'''单切多列'''
c3 = c[..., 2:]
print(c3)
# [[3 4]
# [7 8]
# [6 0]
# [5 6]]
'''行列全切'''
c2 = c[1:3, 1:3]
print(c2)
# [[6 7]
# [5 6]]
产生问题:我是否可以输出某几行中的一列数字呢?
c2 = c[1:3, 1]
print(c2)
'''
c = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[3, 5, 6, 0],
[8, 9, 5, 6]])
'''
# [6 5]
由此可知,只输出某几列中某行数字也是可以的。但可以发现,这样的输出都是连续的行列,如果我想输出连续两列中,偶数行的数组呢?
列表索引:
有教程称之为“高级索引”,自己记忆的时候还是朴素点吧……
这里解释一下为什么可以用列表索引(和切片索引不一样,切片连续,列表不连续)。
numpy.ndarray数组的索引长这样:[行, 列]
实际上,每一行,每一列都相当于一个一维数组。(套娃套起来了)
在此基础上,我就可以进行针对行和列的切片。(如果还是不明白,具体参考列表的切片或是字符串的切片)
这就是行列都能用切片的原因。
那么为什么可以用列表索引?
回想一下列表的索引(列表是1维的),二维数组操作的基础也是一维数组。
可以理解成,数组索引——[行, 列]——在这个方括号中,逗号前面的都是行,逗号后面的都是列。如果有一个索引长这样——c4 = c[[0, 2], 3]——表示:将c数组中第3列,第0行和第2行的值,赋值给c4。
c4 = c[[0, 2], 3]
print(c4)
# [4 0]
列表索引+切片索引:
在明白了列表索引和切片索引后,这个部分就很好理解了——排列组合。
c4 = c[1:3, [1, 2]]
print(c4)
# [[6 7]
# [5 6]]
输出数组中大于某一数字的数:
听起来难,做起来很简单:
c5 = c[c > 4]
print("输出所有大于4的元素", c5)
'''生成的是一个一维列表'''
# 输出所有大于4的元素 [5 6 7 8 5 6 8 9 5 6]
日拱一卒,功不唐捐。