先上结论:
设有基于python
语言的数组arr
,arr[ : , : ]
表示的是对数组中不同维度的索引, 若存在关键字None
则表示维度扩充。
不妨假设
arr
维度为(2,3,4)
,那么arr[1 : 2, 2 : 3, 1 : 3]
即表示在第一个维度上,切片选取索引为1
的元素,在第二个维度上,切片选取索引为2
的元素,最后在第三个维度上,切片选取索引为1、2
的元素。
下面进行更加详细的说明。
首先看一个简单的例子:
# 初始化数组
import numpy as np
arr = np.array([1,2,3])
# 最基本的直接索引,获取索引为0的元素
print(arr[0])
# 采用切片的方式获取部分元素
print(arr[0:2]) # 获取索引为0, 1的两个元素
PS
:数组切片详情参看Python切片索引
实验结果如下:
1
[1, 2]
让我们尝试对这个数组进行arr[ : , : ]
形式的引用:
# 创建数组
arr1 = np.array([1, 2, 3])
# 常规切片
print(arr1[0:2])
print(f'init arr1 is: \n{arr1}\nits shape is: {arr1.shape}\n')
# 尝试arr1[:,:]
try:
print(f'arr1[:,:] is: \n{arr1[:, :]}\n')
except IndexError:
logging.info('arr1[:, :] is wrong\n')
# 尝试arr1[:, None]
try:
print(f'arr1[:, None] is: \n{arr1[:, None]}\nits shape is: {arr1[:, None].shape}\n')
except IndexError:
logging.info('arr1[:, None] is wrong\n')
# 尝试arr1[None, :]
try:
print(f'arr1[None, :] is: \n{arr1[None, :]}\nits shape is: {arr1[None, :].shape}\n')
except IndexError:
logging.info('arr1[None, :] is wrong\n')
# 尝试arr1[:, 0]
try:
print(f'arr1[:, 0] is: \n{arr1[:, 0]}\nits shape is: {arr1[:, 0].shape}\n')
except IndexError:
logging.info('arr1[:, 0] is wrong\n')
# 尝试arr1[0, :]
try:
print(f'arr1[0, :] is: \n{arr1[0, :]}\nits shape is: {arr1[0, :].shape}\n')
except IndexError:
logging.info('arr1[0, :] is wrong\n')
PS
:注意这里的设置,若可以执行,则采用Print
输出(黑色字体),否则使用logging
进行记录(红色字体),logging
相关详见logging的适用
按照顺序进行查看
-
尝试
arr1[:,:]
实验结果如下:(红色字体,表示为logging
信息,存在索引错误)
可见针对维度为(3)
的arr1
不适用这种形式,因为arr1
不存在第二个维度,所以无法进行切片 -
尝试
arr1[:, None]
实验结果如下:(黑色字体,表示为print
信息)
通过关键字None
,发现arr1
的维度增加了1
维 -
尝试
arr1[None, :]
实验结果如下:(黑色字体,表示为print
信息)
通过关键字None
,同样发现arr1
的维度增加了1
维,这次是在原有维度的前面 -
尝试
arr1[:, 1]
实验结果如下:(红色字体,表示为logging
信息,存在索引错误)
同样因为arr1
不存在第二个维度,所以无法进行索引 -
尝试
arr1[1, :]
实验结果如下:(红色字体,表示为logging
信息,存在索引错误)
原因同上。
接下来尝试对二维数组进行操作
But!!!
在此之前需要先明白:每一个维度是如何表示的
数组维度表示
上图中,从上至下按照维度进行划分,颜色相同的表示一个元素,不同的元素组成当前的维度。形象化即,第k
个维度就是数组第k
层括号中的内容。
二维数组的[: , :]
操作
# 初始化数组
arr2 = np.array([[1, 2], [3, 4], [5, 6]])
print(f'init arr2 is: \n{arr2}\nits shape is: {arr2.shape}\n')
# 尝试arr2[0:2, :]
try:
print(f'arr2[0:2,:] is: \n{arr2[0:2, :]}\n')
except IndexError:
logging.info('arr2[0:2, :] is wrong\n')
# arr2[:, 0]
try:
print(f'arr2[:, 0] is: \n{arr2[:, 0]}\nits shape is: {arr2[:, 0].shape}\n')
except IndexError:
logging.info('arr2[:, 0] is wrong\n')
# arr2[0, :]
try:
print(f'arr2[0, :] is: \n{arr2[0, :]}\nits shape is: {arr2[0, :].shape}\n')
except IndexError:
logging.info('arr2[0, :] is wrong\n')
# 尝试arr2[:, None]
try:
print(f'arr2[:, None] is: \n{arr2[:, None]}\nits shape is: {arr2[:, None].shape}\n')
except IndexError:
logging.info('arr2[:, None] is wrong\n')
# 尝试arr2[None, :]
try:
print(f'arr2[None, :] is: \n{arr2[None, :]}\nits shape is: {arr2[None, :].shape}\n')
except IndexError:
logging.info('arr2[None, :] is wrong\n')
# 尝试arr2[:, None, :]
try:
print(f'arr2[:, None, :] is: \n{arr2[:, None, :]}\nits shape is: {arr2[:, None, :].shape}\n')
except IndexError:
logging.info('arr2[:, None, :] is wrong\n')
# arr2[:, :, None]
try:
print(f'arr2[:, :, None] is: \n{arr2[:, :, None]}\nits shape is: {arr2[:, :, None].shape}\n')
except IndexError:
logging.info('arr2[:, :, None] is wrong\n')
同样按照顺序查看
这里输出一下init
数组,便于比较:
-
尝试
arr2[0:2, :]
实验结果如下:(黑色字体,表示为print
信息)
此时可以看出,在第一个维度上,切片选取前两个元素,没有了[5, 6]
,而在第二个维度上全部保留,可对比init
数组查看。 -
尝试
arr2[:, 0]
与arr2[0, :]
实验结果如下:(黑色字体,表示为print
信息)
分别选择第1 or 2维中索引为1的元素,保留剩余维度,可对比init
数组查看 -
尝试
arr2[None, :]
,arr2[:, None, :]
与arr2[:, :, None]
实验结果如下:(黑色字体,表示为print
信息)
从上至下依次是在第1个维度前,已有维度内,最后1个维度后,添加新的维度,可对比init
数组查看
这里需要注意的是:
arr2[None, :]
与arr2[None, :, :]
是等效的,因为这里每一个:
就表示对一个维度的引用,所以两个式子均表达在第一个维度前扩充。
!!!但是,arr2[:, :, None]
不能简写为arr2[:, None]
,后者表示在第一个维度之后添加,而不是最后一个维度后。
实验中其实存在一个问题,即log
与print
没有按照顺序输出,arr1
的log
信息可能在arr2
的print
输出之后,欢迎大佬提出见解!