这个专栏名为《Numpy从入门到精通》,顾名思义,是记录自己学习numpy的学习过程,也方便自己之后复盘!为深度学习的进一步学习奠定基础!希望能给大家带来帮助,爱睡觉的咋祝您生活愉快! 这一篇介绍《Numpy从入门到精通——数组变形|合并数组

在深度学习中,常常会涉及到矩阵的变形。在实际任务中,我们常常需要将处理好的数据以模型能接收的形式发送,然后通过模型计算出一个结果返回。不同模型所要接受的数据的格式是不一样的,这就要求我们将数据处理成符合模型要求的格式。最常见的就是矩阵或者是数组的运算,所以这次我们分享numpy怎么样进行数组变形和合并数组

一、修改数组的形状

首先我们给出numpy中修改向量的一些常用函数:

函数 描述
arr.reshape 重新对向量arr维度进行改变,不修改向量本身
arr.resize 重新对向量arr维度进行改变,修改向量本身
arr.T 对向量arr进行转置
arr.ravel 对向量arr进行展平,即将多维数组变成1维数组,不会产生原数组的副本
arr.flatten 对向量arr进行展平,即将多维数组变成1维数组,返回原数组的副本
arr.squeeze 只能对维数为1的数组降维。对多维数组使用时虽然不会报错,但是不会产生任何影响
arr.transpose 对高维矩阵进行轴对换

下面我们通过具体的代码看每一个函数的效果:

1.1 reshape函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_19.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 10:48 
"""
import numpy as np

arr = np.arange(10)
print(arr)
# 将向量 arr 维度变换为2行5列
print(arr.reshape(2, 5))
# 指定维度时可以只指定行数或列数, 其他用 -1 代替
print(arr.reshape(5, -1))
print(arr.reshape(-1, 5))

输出为:

[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
 [5 6 7 8 9]]
[[0 1]
 [2 3]
 [4 5]
 [6 7]
 [8 9]]
[[0 1 2 3 4]
 [5 6 7 8 9]]

值得注意的是,说设置的行数和列数一定要能够被整除,否则会报错!

1.2 resize函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_20.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 10:52 
"""
import numpy as np

arr = np.arange(10)
print(arr)
# 将向量 arr 维度变换为2行5列
arr.resize(2, 5)
print(arr)

输出为:

[0 1 2 3 4 5 6 7 8 9]
[[0 1 2 3 4]
 [5 6 7 8 9]]

resize是没有返回值的,直接在原数组上进行操作。

1.3 T函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_21.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 10:58 
"""
import numpy as np

arr = np.arange(12).reshape(3, 4)
# 向量 arr 为3行4列
print(arr)
# 将向量 arr 进行转置为4行3列
print(arr.T)

输出为:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[ 0  4  8]
 [ 1  5  9]
 [ 2  6 10]
 [ 3  7 11]]

转置是有返回值的,所有可以用print直接输出出来。

1.4 ravel函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_22.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:00 
"""
import numpy as np

arr = np.arange(6).reshape(2, -1)
print(arr)
# 按照列优先,展平
print("按照列优先,展平")
print(arr.ravel('F'))
# 按照行优先,展平
print("按照行优先,展平")
print(arr.ravel())

输出为:

[[0 1 2]
 [3 4 5]]
按照列优先,展平
[0 3 1 4 2 5]
按照行优先,展平
[0 1 2 3 4 5]

默认情况是按照行优先进行排序,设置“F”可以安装列优先进行展开。

1.5 flatten(order=“C”)函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_23.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:08 
"""
import numpy as np
a =np.floor(10*np.random.random((3,4)))
print(a)
print(a.flatten(order='C'))
print(a)

输出为:

[[4. 5. 5. 7.]
 [3. 7. 3. 0.]
 [0. 4. 6. 0.]]
[4. 5. 5. 7. 3. 7. 3. 0. 0. 4. 6. 0.]
[[4. 5. 5. 7.]
 [3. 7. 3. 0.]
 [0. 4. 6. 0.]]

flatten经常在卷积网络与全连接层之间,一般在网络需要把2维,3维的多维数组转化为一维数组时使用:

1.6 squeeze函数

import numpy as np
 
arr =np.arange(3).reshape(3, 1)
print(arr.shape)  #(3,1)
print(arr.squeeze().shape)  #(3,)
arr1 =np.arange(6).reshape(3,1,2,1)
print(arr1.shape) #(3, 1, 2, 1)
print(arr1.squeeze().shape) #(3, 2)

输出为:

(3, 1)
(3,)
(3, 1, 2, 1)
(3, 2)

squeeze函数主要用于降维,可以把数组中含1的维度去掉。

1.7 transpose函数

import numpy as np
 
arr2 = np.arange(24).reshape(2,3,4)
print(arr2.shape)  #(2, 3, 4)
print(arr2.transpose(1,2,0).shape)  #(3, 4, 2)

输出:

(2, 3, 4)
(3, 4, 2)

还记得我们之前说opencv读取图片是BGR格式的吗?我们可以通过numpy.transpose函数进行轴对换,变成RGB格式,再用plt就能正常显示了!

二、合并数组

合并数组也是比较常见的操作之一,同样的,我们先看有哪些函数然后对这些函数进行说明:

函数 描述
np.append 内存占用大
np.concatenate 没有内存问题
np.stack 沿着新的轴加入一系列数组
np.hstack 栈数组垂直顺序(行)
np.vstack 栈数组垂直顺序(列)
np.dstack 栈数组按顺序深入(沿第3维)
np.vsplit 将数组分解成垂直的多个子数组的列表
zip[iterable,…] 将对象中对应的元素打包成一个个元组构成的zip对象

说明

  • append、concatnate以及stack函数都有一个 axis 参数,用于控制数组合并是按行还是按列排序。
  • append和concatnate函数中待合并的数组必须有相同的行数或列数(满足一个即可)。
  • stack、hstack、dstack函数中待合并的数组必须具有相同的形状( shape)。

2.1 append函数

合并一维数组

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_26.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:40 
"""
import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.append(a, b)
print(c)
# [1 2 3 4 5 6]

输出:

[1 2 3 4 5 6]

合并多维数组

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_27.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:41 
"""
import numpy as np

a = np.arange(4).reshape(2, 2)
b = np.arange(4).reshape(2, 2)
# 按行合并
c = np.append(a, b, axis=0)
print('按行合并后的结果')
print(c)
print('合并后数据维度', c.shape)
# 按列合并
d = np.append(a, b, axis=1)
print('按列合并后的结果')
print(d)
print('合并后数据维度', d.shape)

输出为:

按行合并后的结果
[[0 1]
 [2 3]
 [0 1]
 [2 3]]
合并后数据维度 (4, 2)
按列合并后的结果
[[0 1 0 1]
 [2 3 2 3]]
合并后数据维度 (2, 4)

2.2 concatenate函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_28.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:43 
"""
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])

c = np.concatenate((a, b), axis=0)
print(c)
d = np.concatenate((a, b.T), axis=1)
print(d)

2.3 stack函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_29.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:43 
"""
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(np.stack((a, b), axis=0))

输出为:

[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]

2.4 zip函数

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_30.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:45 
"""
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
c = c = zip(a, b)
for i, j in c:
    print(i, end=",")
	print(j)

输出为:

[1 2],[5 6]
[3 4],[7 8]

zip函数组合两个向量

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :numpy学习 
@File    :task_31.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/4/22 11:49 
"""
import numpy as np

a1 = [1, 2, 3]
b1 = [4, 5, 6]
c1 = zip(a1, b1)
for i, j in c1:
    print(i, end=",")
    print(j)

输出为:

1,4
2,5
3,6