NumPy¶
Numpy 是 Python 中科学计算的核心库。它提供了一个高性能的多维数组对象,以及用于处理这些数组的工具。
数组¶
NumPy的数组类被调用ndarray, 通常用别名array来表示。
属性¶
每个NumPy数组都拥有如下属性:
nidm:数组维度shape:维度大小size:数组大小dtype:数据类型itemsize:元素字节大小, 以bytes为单位nbytes:数组字节大小, 以bytes为单位
In [3]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
print('x.ndim:',x.ndim)
print('x.shape:',x.shape)
print('x.size:',x.size)
print('x.dtype:',x.dtype)
print('x.itemsize:',x.itemsize)
print('x.nbytes:',x.nbytes)
x
x.ndim: 2
x.shape: (3, 3)
x.size: 9
x.dtype: int32
x.itemsize: 4
x.nbytes: 36
Out[3]:
array([[6, 9, 4],
[2, 0, 9],
[5, 5, 9]])
利用列表(list)生成数组¶
利用nd.array从 Pyhon 列表创建数值:
In [4]:
x = np.array([1,2,3,4])
x
Out[4]:
array([1, 2, 3, 4])
不同于Python列表, NumPy 要求数组必须包含同一类型的数据。如果类型不匹配, NumPy 将会向上转换(如果可行)。
In [5]:
x = np.array([1.0, 2, 3.0, 4])
x
Out[5]:
array([1., 2., 3., 4.])
如果希望明确设置数组的数据类型,可以用dtype变量:
In [6]:
x = np.array([1, 2, 3, 4], dtype=np.float32)
x
Out[6]:
array([1., 2., 3., 4.], dtype=float32)
利用list构建多维数组:
In [7]:
x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
x
Out[7]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
利用NumPy内置方法创建数值¶
np.zeros():创建全 0 数值
In [8]:
# 创建一个长度为5的全0数组
x = np.zeros(5)
x
Out[8]:
array([0., 0., 0., 0., 0.])
np.ones():创建全 1 数组
In [9]:
# 创建一个3*3的q全1矩阵
x = np.ones((3,3), dtype=float)
x
Out[9]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
np.eye():创建一个单位矩阵
In [10]:
# 创建一个3*3的单位矩阵
x = np.eye(3)
x
Out[10]:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
np.full(shape, fill_value):创建一个维数为shape、值为fill_value的数组
In [11]:
# 创建一个维数为3*3、值全为2.0的浮点数型数组
x = np.full((3,3), fill_value=2.0)
x
Out[11]:
array([[2., 2., 2.],
[2., 2., 2.],
[2., 2., 2.]])
序列数组:
np.arange(start, stop, step):创建一个从start到stop,步长为step的序列数组。np.linspace(start, stop, num=50):创建一个从start到stop,元素个数为num的序列数组。
In [12]:
# 创建一个从0到10,步长为2的序列数组
x = np.arange(0, 10, 2)
x
Out[12]:
array([0, 2, 4, 6, 8])
In [13]:
# 创建一个从0到10,元素个数为5的序列数组
x = np.linspace(0, 10, 5)
x
Out[13]:
array([ 0. , 2.5, 5. , 7.5, 10. ])
随机分布数组:
np.random.random():创建一个由 0 ~ 1 均匀分布生成的随机数组成的数组np.random.normal(loc=0.0, scale=1.0, size=None):创建一个由均值为loc、方差为scale的正态分布生成的随机数组成的数组np.random.randint(low, high=None, size=None):创建一个由low~high均匀分布生成的随机整数组成的数值
In [14]:
# 创建一个3×3、由0~1均匀分布随机数组成的数组
x = np.random.random((3, 3))
x
Out[14]:
array([[0.15338635, 0.12742116, 0.95750969],
[0.36620692, 0.18246738, 0.15248931],
[0.22651305, 0.18201162, 0.39888777]])
In [15]:
# 创建一个3×3、由均值为0、方差为1的正态分布随机数组成的数组
x = np.random.normal(0, 1, (3, 3))
x
Out[15]:
array([[ 1.60544151, 1.53877914, 0.54658101],
[ 0.29518817, -1.31794875, -0.75930664],
[ 1.03449542, -0.53970085, 1.11143185]])
In [16]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
x
Out[16]:
array([[7, 4, 4],
[1, 9, 2],
[8, 0, 0]])
数组操作¶
基本运算¶
数组上的运算与 Python 类似,支持 Python 原生的算术运算符,标准的加、减、乘、除都可以使用。
In [17]:
x = np.arange(4)
print("x =", x)
print("x + 5 =", x + 5)
print("x * 2 =", x * 2)
print("x / 2 =", x / 2)
print("x // 2 =", x // 2)
print("-x = ", -x)
print("x ** 2 = ", x ** 2)
print("x % 2 = ", x % 2)
x = [0 1 2 3]
x + 5 = [5 6 7 8]
x * 2 = [0 2 4 6]
x / 2 = [0. 0.5 1. 1.5]
x // 2 = [0 0 1 1]
-x = [ 0 -1 -2 -3]
x ** 2 = [0 1 4 9]
x % 2 = [0 1 0 1]
运算符与通用函数的对应关系如下表所示:
| 运算符 | 对应的通用函数 | 描述 |
|---|---|---|
| np.add | 加法运算 | |
| np.subtract | 减法运算 | |
| np.negative | 负数运算 | |
| * | np.multipy | 乘法运算 |
| / | np.divide | 除法运算 |
| // | np.floor_divide | 取商除法运算 |
| ** | np.power | 指数运算 |
| & | np.mod | 取模(余数)除法运算 |
索引与切片¶
- 索引:获取某个元素
- 切片:获取某些元素
In [18]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
x
Out[18]:
array([[6, 6, 1],
[4, 8, 7],
[2, 6, 5]])
In [19]:
# 索引
x[1,1]
Out[19]:
8
In [20]:
# 切片
x[1:,1:]
Out[20]:
array([[8, 7],
[6, 5]])
数组排序¶
- np.sort(a,
axis=1):
a表示要排序的数值,axis=0表示按列排序(axis=1表示按行排序)
In [21]:
# 创建一个4×6、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (4, 6)))
x
Out[21]:
array([[7, 0, 1, 0, 9, 4],
[5, 2, 3, 1, 7, 2],
[1, 2, 7, 3, 5, 8],
[0, 8, 9, 0, 4, 8]])
In [22]:
# 按列排序
np.sort(x, axis = 0)
Out[22]:
array([[0, 0, 1, 0, 4, 2],
[1, 2, 3, 0, 5, 4],
[5, 2, 7, 1, 7, 8],
[7, 8, 9, 3, 9, 8]])
In [23]:
# 按列排序
np.sort(x, axis = 1)
Out[23]:
array([[0, 0, 1, 4, 7, 9],
[1, 2, 2, 3, 5, 7],
[1, 2, 3, 5, 7, 8],
[0, 0, 4, 8, 8, 9]])
数组变形¶
reshape()方法
In [24]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
x
Out[24]:
array([[0, 0, 9],
[6, 4, 5],
[5, 6, 1]])
In [25]:
print('通过变形获得的行向量:\n', x.reshape((1, 9)))
print('通过变形获得的列向量:\n', x.reshape((9, 1)))
通过变形获得的行向量:
[[0 0 9 6 4 5 5 6 1]]
通过变形获得的列向量:
[[0]
[0]
[9]
[6]
[4]
[5]
[5]
[6]
[1]]
数组转置¶
In [26]:
x = (np.random.randint(0, 10, (2, 3)))
x
Out[26]:
array([[6, 5, 1],
[1, 2, 4]])
In [27]:
x.T
Out[27]:
array([[6, 1],
[5, 2],
[1, 4]])
拼接与拆分¶
拼接方法¶
np.concatenate((a1, a2, ...), axis=0):按垂直(水平axis=1)拼接数组元组(a1, a2, ...)或数值列表[a1, a2, ...]np.vstack((a1, a2, ...)):按垂直方向拼接数组元组(a1, a2, ...)或数值列表[a1, a2, ...]np.hstack((a1, a2, ...)):按水平方向拼接数组元组(a1, a2, ...)或数值列表[a1, a2, ...]
In [28]:
x = np.array([[1,2,3,4],
[1,2,3,4]])
x
Out[28]:
array([[1, 2, 3, 4],
[1, 2, 3, 4]])
In [29]:
# 按垂直方向拼接数组x和x
print('通过np.concatenate()方法拼接:\n',np.concatenate((x,x)))
print('通过np.vstack()方法拼接:\n',np.vstack((x,x)))
通过np.concatenate()方法拼接:
[[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]]
通过np.vstack()方法拼接:
[[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]]
In [30]:
# 按水平方向拼接数值x和x
print('通过np.concatenate()方法拼接:\n',np.concatenate((x,x),axis=1))
print('通过np.vstack()方法拼接:\n',np.hstack((x,x)))
通过np.concatenate()方法拼接:
[[1 2 3 4 1 2 3 4]
[1 2 3 4 1 2 3 4]]
通过np.vstack()方法拼接:
[[1 2 3 4 1 2 3 4]
[1 2 3 4 1 2 3 4]]
拆分方法¶
np.split(ary, indices_or_sections, axis=0):ary为要拆分的数值,indices_or_sections为拆分节点序列,axis=0表示按竖直方向拆分(axis=1表示按竖直方向拆分)np.hsplit():按水平方向拆分np.vsplit():按竖直方向拆分
一维数组:
In [31]:
x = np.arange(9)
print(x)
print(np.split(x,3))
print(np.split(x,[2,5,7]))
[0 1 2 3 4 5 6 7 8]
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
[array([0, 1]), array([2, 3, 4]), array([5, 6]), array([7, 8])]
二维数组:
In [32]:
# 按竖直方向拆分
y = (np.random.randint(0, 10, (3, 3)))
print('通过np.split()方法拆分:\n',np.split(y, 3))
print('通过np.hsplit()方法拆分:\n',np.vsplit(y, 3))
通过np.split()方法拆分:
[array([[8, 7, 4]]), array([[6, 7, 2]]), array([[9, 8, 0]])]
通过np.hsplit()方法拆分:
[array([[8, 7, 4]]), array([[6, 7, 2]]), array([[9, 8, 0]])]
In [33]:
# 按水平方向拆分
print('通过np.split()方法拆分:\n',np.split(y, 3, axis=1))
print('通过np.hsplit()方法拆分:\n',np.hsplit(y, 3))
通过np.split()方法拆分:
[array([[8],
[6],
[9]]), array([[7],
[7],
[8]]), array([[4],
[2],
[0]])]
通过np.hsplit()方法拆分:
[array([[8],
[6],
[9]]), array([[7],
[7],
[8]]), array([[4],
[2],
[0]])]
通用函数¶
NumPy
提供熟悉的数学函数,例如sin,cos和exp等,在
NumPy 中,这些被称为“通用函数”(ufunc)。
In [34]:
x = np.arange(3)
x
Out[34]:
array([0, 1, 2])
In [35]:
np.exp(x)
Out[35]:
array([1. , 2.71828183, 7.3890561 ])
In [36]:
np.sqrt(x)
Out[36]:
array([0. , 1. , 1.41421356])
In [37]:
np.add(x,x)
Out[37]:
array([0, 2, 4])
NumPy提供了大量的通用函数,具体情况可上官网查看,这里就不一一介绍了。
广播¶
广播是一种强有力的机制,通过它 NumPy 可以使不同大小的矩阵在一起进行数学计算。
In [38]:
a = np.array([[ 0.0, 0.0, 0.0],
[10.0,10.0,10.0],
[20.0,20.0,20.0],
[30.0,30.0,30.0]])
b = np.array([1.0,2.0,3.0])
a + b
Out[38]:
array([[ 1., 2., 3.],
[11., 12., 13.],
[21., 22., 23.],
[31., 32., 33.]])
以上内容参考了 NumPy 官方教程和《Python科学计算手册》一书
个人水平有限,文章中存在的任何问题请大家在评论中或私信我指正,我会认真修改或给出回馈。