最近看代码发现很多NumPy的基本代码都不太理解,因此重新回顾学习一下。

参考NumPy Ndarray 对象 | 菜鸟教程 (runoob.com)

NumPy Ndarray对象

NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。

ndarray 对象是用于存放同类型元素的多维数组。

ndarray 中的每个元素在内存中都有相同存储大小的区域。

创建一个 ndarray 只需调用 NumPy 的 array 函数即可:

1
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

参数说明:

名称 描述
object 数组或嵌套的数列
dtype 数组元素的数据类型,可选
copy 对象是否需要复制,可选
order 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok 默认返回一个与基类类型一致的数组
ndmin 指定生成数组的最小维度

numpy.array 理解

首先NumPy处理的都是对象,即Ndarray对象。其实numpy.array就是ndarray的构造器。

NumPy创建数组

numpy.array

1
2
3
4
5
6
7
8
9
import numpy as np
a = np.array([1, 2, 3])
b = np.array([[1, 2], [3, 4]])
print('a = ', a)
print('b = ', b)
结果:
a = [1, 2, 3]
b = [[1 2]
[3 4]]

numpy.empty

numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:

1
numpy.empty(shape, dtype = float, order = 'C')

参数说明:

参数 描述
shape 数组形状
dtype 数据类型,可选
order 有”C”和”F”两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
1
2
3
4
5
6
7
8
import numpy as np 
x = np.empty([3,2], dtype = int)
print (x)

结果:
[[ 6917529027641081856 5764616291768666155]
[ 6917529027641081859 -5764598754299804209]
[ 4497473538 844429428932120]]

注意 − 数组元素为随机值,因为它们未初始化。

numpy.zeros

创建指定大小的数组,数组元素以 0 来填充:

1
numpy.zeros(shape, dtype = float, order = 'C')

参数说明:

参数 描述
shape 数组形状
dtype 数据类型,可选
order ‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np

# 默认为浮点数
x = np.zeros(5)
print(x)

# 设置类型为整数
y = np.zeros((5,), dtype = np.int)
print(y)

# 自定义类型
z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])
print(z)

结果:
[0. 0. 0. 0. 0.]
[0 0 0 0 0]
[[(0, 0) (0, 0)]
[(0, 0) (0, 0)]]

numpy.ones

创建指定形状的数组,数组元素以 1 来填充:

1
numpy.ones(shape, dtype = None, order = 'C')

参数说明:

参数 描述
shape 数组形状
dtype 数据类型,可选
order ‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np

# 默认为浮点数
x = np.ones(5)
print(x)

# 自定义类型
x = np.ones([2,2], dtype = int)
print(x)

结果:
[1. 1. 1. 1. 1.]
[[1 1]
[1 1]]

从已有的数组创建数组

numpy.array

输入是数组或嵌套的数列

numpy.asarray

numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。

1
numpy.asarray(a, dtype = None, order = None)

参数说明:

参数 描述
a 任意形式的输入参数,可以是列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组
dtype 数据类型,可选
order 可选,有”C”和”F”两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np 

x = [1,2,3] # 将列表转换为 ndarray
y = (1,2,3) # 将元组转换为 ndarray
z = [(1,2,3),(4,5)] # 将元组列表转换
a = np.asarray(x)
b = np.asarray(y)
c = np.asarray(z)
print (a)
print (b)
print (c)

结果:
[1 2 3]
[1 2 3]
[(1, 2, 3) (4, 5)]

NumPy 从数值范围创建数组

numpy.arange

numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下:

1
numpy.arange(start, stop, step, dtype)

根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。

参数说明:

参数 描述
start 起始值,默认为0
stop 终止值(不包含)
step 步长,默认为1
dtype 返回ndarray的数据类型,如果没有提供,则会使用输入数据的类型。
1
2
3
4
5
6
7
8
9
10
import numpy as np

x = np.arange(5) # 生成 0 到 5 的数组
y = np.arange(5, dtype = float) # 设置返回类型位 float
print (x)
print (y)

结果:
[0 1 2 3 4]
[0. 1. 2. 3. 4.]

numpy.linspace

numpy.linspace 函数用于创建一个一维数组,数组是一个等差数列构成的,格式如下

1
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

参数说明:

参数 描述
start 序列的起始值
stop 序列的终止值,如果endpoint为true,该值包含于数列中
num 要生成的等步长的样本数量,默认为50
endpoint 该值为 true 时,数列中包含stop值,反之不包含,默认是True。
retstep 如果为 True 时,生成的数组中会显示间距,反之不显示。
dtype ndarray 的数据类型
1
2
3
4
5
6
7
8
9
10
import numpy as np

a = np.linspace(1,10,10) # 设置起始点为 1 ,终止点为 10,数列个数为 10
b = np.linspace(1,1,10) # 设置元素全部是1的等差数列
print(a)
print(b)

结果:
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

numpy.logspace

numpy.logspace 函数用于创建一个于等比数列。格式如下:

1
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)

base 参数意思是取对数的时候 log 的下标。

参数 描述
start 序列的起始值为:base ** start
stop 序列的终止值为:base ** stop。如果endpoint为true,该值包含于数列中
num 要生成的等步长的样本数量,默认为50
endpoint 该值为 true 时,数列中中包含stop值,反之不包含,默认是True。
base 对数 log 的底数。
dtype ndarray 的数据类型
1
2
3
4
5
6
7
8
9
10
11
import numpy as np

a = np.logspace(1.0, 2.0, num = 10) # 默认底数是 10
b = np.logspace(0,9,10,base=2) # 将对数的底数设置为 2
print('a = ', a)
print('b = ', b)

结果:
a = [ 10. 12.91549665 16.68100537 21.5443469 27.82559402
35.93813664 46.41588834 59.94842503 77.42636827 100. ]
b = [ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]

运用ndarray.reshape

先创建需要的元素总数,之后改变数组维度。

numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下:

1
numpy.reshape(arr, newshape, order='C')
  • arr:要修改形状的数组
  • newshape:整数或者整数数组,新的形状应当兼容原有形状
  • order:’C’ — 按行,’F’ — 按列,’A’ — 原顺序,’k’ — 元素在内存中的出现顺序。
1
2
3
4
5
6
7
8
9
10
11
a = np.arange(12)

b = a.reshape(3, 4)
print("a = ", a)
print("b = ", b)

结果:
a = [ 0 1 2 3 4 5 6 7 8 9 10 11]
b =[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]

ndarray.resize

resize有两种使用方法

一种是没有返回值的,直接对原始的数据进行修改,还有一种用法是有返回值的,所以不会修改原有的数组值。

无返回值,直接修改原始数组的大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = np.arange(12)

a.resize((3, 4))
print("a = ", a)

结果:
a = [[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]

# 这一步不可以通过赋值来实现

b = b.resize((3, 4))
print("b = ", b)

结果:
b = None

有返回值,不对原始数据进行修改

numpy.resize 函数返回指定大小的新数组。

如果新数组大小大于原始大小,则包含原始数组中的元素的副本。

1
numpy.resize(arr, shape)
  • arr:要修改大小的数组
  • shape:返回数组的新形状
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a = np.arange(12)
b = np.resize(a, (3, 4))

print("a = ", a)
print("b = ", b)

结果:
a = [ 0 1 2 3 4 5 6 7 8 9 10 11]
b =[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]

# 如果新数组大小大于原始大小,则包含原始数组中的元素的副本。
b = np.resize(a, (4, 4))
print("b = ", b)
b = [[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 1, 2, 3]]

排列维度

numpy transpose功能为重新排列维度,参数为初始维度所在的最终维度,一定要写满所有的维度。

pytorch的permute和numpy的transpose功能和用法一样,pytorch的transpose功能为交换两个维度,多次使用可以达到permute的效果,需要两个参数,为需要交换的维度,因此参数顺序不重要。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import torch
import numpy as np

# numpy transpose
x = np.random.rand(2,3,4)
print(x.transpose(2,0,1).shape) # [4,2,3]


# pytorch transpose permute
y = torch.randn(2,3,4) # [2,3,4]

# 对于transpose
y.transpose(0,1) # [3,2,4]
# y.transpose(0,2,1) # 报错,操作不了多维

# 对于permute
y.permute(1,0,2) # [3,2,4],必须写满所有的维度才不报错
# y.permute(0,1) # 报错,number of dims don't match in permute"