索引、切片和变换维度
索引和切片
通过index
- 与大家熟悉的编程语言的索引方式一致:一维数组用a[index],二维数组用a[index1][index2],以此类推。
- numpy风格的索引,用一个[]符号索引,例如:a[1][1] <–> a[1, 1]。
- start : end,索引,即切片,例如:a=[0,1,2,3,4,5,6,7,8,9],想选取[3,4,5]的操作是a[3:6];特殊的,只写一个“:”,即a[:]是该维度所有数据都取;此用法可以实现数组的反向,实现:a[:-1]。
- start : end : ste,增加一个步长,可以实现间隔取数。
- ::ste,双冒号索引,此用法可以实现数据的逆序,实现:a = a[::-1],a就变为[9,8,7,6,5,4,3,2,1,0],如果用[::-2]的话,就是倒序间隔一个采样。
- …:三点号索引方式;比如有一个四维数据a[4, 28, 28 3],使用a[1, …]的话,意思是第一维取第一行,后面的数据全取。
使用tensorflow方法
tf.gather
对于多维数组,可以实现某一维度的数据可以任一取,例如一个shaoe为a = [4, 28, 28, 3]的数据,
我们想在w维度,即第三维的数据上实现索引号为[7,3,25,1]的采样顺序,那么可以直接用tf.gather(a, axis=2,indices=[7,3,25,1]),得到的就是一个shaoe为[4, 28, 4, 3]的数据。
tf.gather_nd
同时操作多个维度的数据时使用,用法:tf.gather_nd(tensor, [index, index…]),或者:tf.gather_nd(tensor, [[1,1],[2,2]…]) 实际就是取tensor[index, index,…]的数据。
recommended indices format(格式如下):
- [[0], [1], …]
- [[0,0], [1,1], …]
- [[0,0,0], [1,1,1], …]
tf.boolean_mask
利用ture或false来实现采样的方式。
数据维度变换
数据的属性:shape就是数据的形状,ndim时数据的维度数。
reshape
reshape可以改变数据维度,但是不改变数据本身,因此变化是双向的。
a = tf.random.normal([4, 28, 28, 3])
print(a.shape)
print(a.ndim)
# 降为三位
a = tf.reshape(a, [4, 784, 3])
print(a.shape)
print(a.ndim)
# 降为二维
a = tf.reshape(a, [4, 784*3])
print(a.shape)
print(a.ndim)
# 反向升为三维
a = tf.reshape(a, [4, 784, 3])
print(a.shape)
print(a.ndim)
# 反向升为四维
a = tf.reshape(a, [4, 28, 28, 3])
print(a.shape)
print(a.ndim)
输出:
4, 28, 28, 3)
4
(4, 784, 3)
3
(4, 2352)
2
(4, 784, 3)
3
(4, 28, 28, 3)
4
transpose
transpose可以交换维度位置:
# 创建一个tensor
b = tf.random.normal([4, 20, 28, 3])
print(b.shape)
print(b.ndim)
# 交换最后两个轴
b = tf.transpose(b, perm=[0, 1, 3, 2])
print(b.shape)
print(b.ndim)
# 第一个轴不变,后面三个轴逆序
b = tf.transpose(b, perm=[0, 3, 2, 1])
print(b.shape)
print(b.ndim)
输出:
(4, 20, 28, 3)
4
(4, 20, 3, 28)
4
(4, 28, 3, 20)
4
增加和减少维度
squeeze:去掉某一维度数据,当且仅当shape=1的dim可以使用此方法去掉;当指定轴时会去掉指定轴的dim,当没有指定轴时会直接去掉全部shape=1的dim。
expand_dims:在固定位置增加一维数据,当给定的轴是正数时,是在给定的轴的前面增加,当给定的轴是负数时,是给定的轴的后面增加。
# 创建一个tensor
a = tf.reshape(a, [4, 28, 28, 3])
print(a.shape)
print(a.ndim)
# 在0维前面增加一维
a = tf.expand_dims(a, axis=0)
print(a.shape)
print(a.ndim)
# 去掉第0维
a = tf.squeeze(a, axis=0)
print(a.shape)
print(a.ndim)
# 在第二维前面增加一维
a = tf.expand_dims(a, axis=2)
print(a.shape)
print(a.ndim)
#去掉第二维
a = tf.squeeze(a, axis=2)
print(a.shape)
print(a.ndim)
# 创建一个tensor
a =tf.random.normal( [4, 1, 28, 1, 1, 2, 1])
print(a.shape)
print(a.ndim)
# 不指定轴时默认去掉全部shape=1的dim
a = tf.squeeze(a)
print(a.shape)
print(a.ndim)
输出:
(4, 28, 28, 3)
4
(1, 4, 28, 28, 3)
5
(4, 28, 28, 3)
4
(4, 28, 1, 28, 3)
5
(4, 28, 28, 3)
4
(4, 1, 28, 1, 1, 2, 1)
7
(4, 28, 2)
3