目录
1. 改变 ndarray 数组形状
1.1 reshape()
1.2 扁平化函数 ravel() 和 flatten()
1.3 resize()
1.4 转置函数 transpose()
2. 将不同数组堆叠在一起
2.1 stack()
2.2 vstack() 和 hstack()
前面两小节讲了ndarray 一维数组、二维数组的一些常用操作,对ndarray有了一些感性的认识。那如果是多维数组呢,我们需要更广阔的视角来看看 ndarray,也就是 Numpy 模块的主要对象,同构多维数组。
ndarray 可以看成一个元素表(通常是数字),所有的类型都相同(在创建或者定义时候就已经确定,不能修改),由非负整数元组索引。在Numpy 维度称之为轴。
1. 改变 ndarray 数组形状
1.1 reshape()
一维数组有一个轴,长度即它的元素个数。
二维数组有两个轴,第一个轴的长度是行的个数,第二个轴的长度是行的元素个数。
而秩,即轴的数量或者维度的数量
回忆一下之前说过的函数,看看二维数组的秩、轴、或者说维度
import numpy as np
x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]],np.int32)
print(x)
print(x.ndim) #秩,即轴的数量或维度的数量
print(x.shape) #数组的维度,对于矩阵,n 行 m 列
print(x.size) #数组元素的总个数,相当于 .shape 中 n*m 的值
运行结果是
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
2
(4, 3)
12
可以看出,这个ndarray的形状就是(4,3),即有 4 行数据,每行 3 个数据。
那如果想改变这个ndarray的形状呢,最常用的就是 reshape 函数
y=x.reshape(3,2,2) # reshape不会改变原来ndarray数据的形状,只会返回一个新的
print(y)
print(y.ndim) #秩,即轴的数量或维度的数量
print(y.shape) #数组的维度,对于矩阵,n 行 m 列
print(y.size) #数组元素的总个数,相当于 .shape 中 n*m 的值
运行结果是
[[[ 1 2]
[ 3 4]]
[[ 5 6]
[ 7 8]]
[[ 9 10]
[11 12]]]
3
(3, 2, 2)
12
可以看到这个新 ndarray的形状就是(3,2,2),即有 3 行,每行有 2 个子数组,每个子数组有2个元素。
如果在 reshape 操作中将 size 指定为-1,则会自动计算其他的 size 大小:
print("*"*40)
print(x)
x.reshape(4,-1) #成功了返回 None
print(x)
运行结果是
****************************************
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
1.2 扁平化函数 ravel() 和 flatten()
想将多维数组转化为一维数组,一般有 ravel() 和 flatten(),两者都能实现这个效果
代码如下
print("*"*40)
print(x)
print("*"*40)
print(x.ravel())
print(x)
print("*"*40)
print(x.flatten())
print(x)
运行结果如下
****************************************
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
****************************************
[ 1 2 3 4 5 6 7 8 9 10 11 12]
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
****************************************
[ 1 2 3 4 5 6 7 8 9 10 11 12]
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
但是ravel() 和 flatten()两者功能相同,在内存上有很大的不同,一般推荐使用 flatten(),为什么呢?
因为flatten()分配了新的内存,返回的是一个真实的数组,而ravel()返回的是一个数组的视图,大家可以用mysql里面的视图去理解,但是又不完全一样,因为ravel() 返回的数组地址和原数组并不一样,有点类似于引用,修改视图的时候可能会影响原本的数组。也可以用深拷贝和浅拷贝来类比。
所以,我非常不推荐使用 ravel(),除非你就是想利用这个特性。
1.3 resize()
reshape() 改变 ndarray 的形状后返回副本,原有数组不会变化,resize() 则会修改数组本身
代码如下
print("*"*40)
print(x)
print(x.resize(2,6)) #成功了返回 None
print(x)
运行结果如下
****************************************
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
None
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
1.4 转置函数 transpose()
简单来说,就相当于数学中的转置,在矩阵中,转置就是把行与列相互调换位置;
但是它返回的是一个副本,原有的数组结构没有改变。
代码段
print("*"*30)
print(x)
print("*"*30)
print(x.transpose())
print("*"*30)
print(x)
运行结果
******************************
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
******************************
[[ 1 7]
[ 2 8]
[ 3 9]
[ 4 10]
[ 5 11]
[ 6 12]]
******************************
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
2. 将不同数组堆叠在一起
- stack():沿着新的轴加入一系列数组。
- vstack():堆栈数组垂直顺序(行)
- hstack():堆栈数组水平顺序(列)。
- dstack():堆栈数组按顺序深入(沿第三维)。
- concatenate():连接沿现有轴的数组序列。
2.1 stack()
按照指定的轴对数组序列进行联结。
语法格式:numpy.stack(arrays, axis=0, out=None)
参数:arrays :数组序列,数组的形状(shape)必须相同;
axis参数指定新轴在结果尺寸中的索引。例如,如果axis=0,它将是第一个维度,如果axis=-1,它将是最后一个维度。不太好理解,大家直接看代码运行结果吧,或者等有需要时候再仔细看。
print("*"*30)
print(x)
z=x
print("*"*30)
print(np.stack((x,z)))
print("*"*30)
print(np.stack((x,z),0))
print("*"*30)
print(np.stack((x,z),1))
运行结果
******************************
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
******************************
[[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]]
******************************
[[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]]
******************************
[[[ 1 2 3 4 5 6]
[ 1 2 3 4 5 6]]
[[ 7 8 9 10 11 12]
[ 7 8 9 10 11 12]]]
2.2 vstack() 和 hstack()
vstack() 沿着第一个轴堆叠数组。
语法格式:numpy.vstack(tup)
参数:tup:ndarrays数组序列,如果是一维数组进行堆叠,则数组长度必须相同;除此之外,其它数组堆叠时,除数组第一个轴的长度可以不同,其它轴长度必须一样。
hstack()沿着第二个轴堆叠数组
语法格式:numpy.hstack(tup)
参数:tup:ndarrays数组序列,除了一维数组的堆叠可以是不同长度外,其它数组堆叠时,除了第二个轴的长度可以不同外,其它轴的长度必须相同。原因在于一维数组进行堆叠是按照第一个轴进行堆叠的,其他数组堆叠都是按照第二个轴堆叠的。
看代码更清楚点
print("*"*30)
print(x)
z=x
print("*"*30)
print(np.vstack((x,z)))
print("*"*30)
print(np.hstack((x,z)))
运行结果如下
******************************
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
******************************
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]
[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]]
******************************
[[ 1 2 3 4 5 6 1 2 3 4 5 6]
[ 7 8 9 10 11 12 7 8 9 10 11 12]]
今天写累了,先到这里吧