3.4 数组操作

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]])

你可能感兴趣的:(3.4 数组操作)