3.4.1 变形
关于数组的变形除了3.2节介绍的reshape()函数,NumPy还有其他操作变形的函数和方法,示例代码:
>>>a = np.random.randint(1, 10, size=(2, 6))
>>>a
array([[2, 4, 3, 7, 4, 7],
[8, 7, 6, 1, 2, 5]])
>>>np.ravel(a)
array([2, 4, 3, 7, 4, 7, 8, 7, 6, 1, 2, 5]) #返回成行向量形式,原数组形状不变
>>>a
array([[2, 4, 3, 7, 4, 7],
[8, 7, 6, 1, 2, 5]])
>>>a.T #返回数组a的转置矩阵,有返回值,原数组形状不变
array([[2, 8],
[4, 7],
[3, 6],
[7, 1],
[4, 2],
[7, 5]])
>>>a
array([[2, 4, 3, 7, 4, 7],
[8, 7, 6, 1, 2, 5]])
>>>a.resize(6, 2) #与转置不同,resize()函数以行元素递进,依次按照参数要求进行重新排列,无返回值,原数组发生改变
>>>a
array([[2, 4],
[3, 7],
[4, 7],
[8, 7],
[6, 1],
[2, 5]])
>>>a.reshape(2, 6) #与resize()功能相同,有返回值,原数组不变
array([[2, 4, 3, 7, 4, 7],
[8, 7, 6, 1, 2, 5]])
>>>a
array([[2, 4],
[3, 7],
[4, 7],
[8, 7],
[6, 1],
[2, 5]])
以上函数或方法的功能及相关注意事项,如下表所示:
名称 | 函数还是方法 | 功能 | 是否有返回值 | 原数组是否发生改变 |
---|---|---|---|---|
ravel() | 函数 | 转换成行向量 | 有 | 不变 |
a.T | 方法 | 转置 | 有 | 不变 |
a.resize() | 方法 | 数组变形 | 无 | 改变 |
a.reshape() | 方法 | 数组变形 | 有 | 不变 |
3.4.2 拼接
两个数组合并成一个数组叫做拼接,根据方向不同,分为垂直拼接vstack()和水平拼接hstack(),示例代码:
>>>a = np.random.randint(1, 9, size = (2, 4))
>>>a
array([[6, 3, 8, 2],
[4, 6, 4, 1]])
>>>b = np.random.randint(1, 9, size = (3, 4))
>>>b
array([[2, 6, 2, 6],
[3, 5, 3, 5],
[6, 7, 1, 6]])
>>>np.vstack((a, b))
array([[6, 3, 8, 2],
[4, 6, 4, 1],
[2, 6, 2, 6],
[3, 5, 3, 5],
[6, 7, 1, 6]])
>>>c = np.random.randint(1, 9, size = (3, 2))
>>>c
array([[6, 4],
[2, 5],
[4, 5]])
>>>d = np.random.randint(1, 9, size = (3, 4))
>>>d
array([[5, 1, 1, 7],
[7, 4, 4, 1],
[4, 4, 7, 3]])
>>>np.hstack((c, d))
array([[6, 4, 5, 1, 1, 7],
[2, 5, 7, 4, 4, 1],
[4, 5, 4, 4, 7, 3]])
注意,垂直拼接中两个数组的列数目要保持一致,水平拼接中两个数组的行数目要保持一致,否则会报错。
3.4.3 切分
与拼接相对应的是vsplit()和hsplit()函数,即对数组进行垂直切分和水平切分,其中第一个参数是待切分的数组,第二个参数表示切分数组的个数。示例代码:
>>>a = np.random.randint(1, 100, size = (6, 2))
>>>a
array([[28, 57],
[67, 37],
[36, 47],
[65, 51],
[26, 69],
[20, 17]])
>>>np.hsplit(a, 3)
[array([[28, 57],[67, 37]]),
array([[36, 47],[65, 51]]),
array([[26, 69],[20, 17]])]
>>>b = np.random.randint(1, 100, size = (2, 6))
>>>b
array([[13, 4, 71, 86, 70, 99],
[81, 84, 75, 83, 44, 74]])
>>>np.vsplit(b, 3)
[array([[13, 4],[81, 84]]),
array([[71, 86],[75, 83]]),
array([[70, 99],[44, 74]])]
3.4.4 复制
探讨数组复制之前,先说明一下数组赋值,Python语言一切对象皆变量,其赋值的含义代表两变量共享同一块内存空间,这条原则对于数组赋值同样适用,当新赋值数组元素值发生改变时,原数组元素值同样发生改变。示例代码:
>>>a = np.array([[1, 2, 3], [4, 5, 6]])
>>>a
array([[1, 2, 3],
[4, 5, 6]])
>>>b = a
>>>id(a)
1366556467968
>>>id(b) #id()函数指向同一个对象
1366556467968
>>>b[0, 2] = 555
>>>a
array([[ 1, 2, 555],
[ 4, 5, 6]])
对于NumPy,分为浅复制和深复制两种,浅复制即创建原数组的视图view(),其功能与赋值类似,视图与原数组共享同一块内存,原数组的值随着视图的改变而改变,示例代码:
>>>a = np.array([[1, 2, 3], [4, 5, 6]])
>>>v = a.view()
>>>v
array([[1, 2, 3],
[4, 5, 6]])
>>>v[0, 2] = 23
>>>a
array([[ 1, 2, 23],
[ 4, 5, 6]])
深复制使用NumPy中的copy()方法,其作用是创建一块新的内存空间给复制对象,即复制后的数组元素对原数组没有影响,示例代码:
>>>a = np.array([[1, 2, 3], [4, 5, 6]])
>>>c = a.copy()
>>>c[0, 2] = 23
>>>a
array([[1, 2, 3],
[4, 5, 6]])
深复制也可以使用numpy.copy()函数,其作用与数组的copy()方法一致,示例代码:
>>>a = np.array([[1, 2, 3], [4, 5, 6]])
>>>c = np.copy(a)
>>>c[0, 2] = 23
>>>c
array([[ 1, 2, 23],
[ 4, 5, 6]])
>>>a
array([[1, 2, 3],
[4, 5, 6]])