Numpy¶
Numpy 是 Python 中用于科学计算的基本包。 它是一个 Python 库,提供多维数组对象、各种派生对象(如屏蔽数组和矩阵) ,以及用于数组快速操作的各种例程,包括数学、逻辑、形状操作、排序、选择、 i/o、离散傅立叶变换、基本线性代数、基本统计操作、随机模拟等等。
数组¶
Numpy 包的核心是ndarray
对象,封装了同类数据类型的 n 维数组,通常用别名array
来表示。
属性¶
每个Numpy
数组都拥有如下属性:
nidm
:数组维度shape
:维度大小size
:数组大小dtype
:数据类型itemsize
:元素字节大小, 以bytes
为单位nbytes
:数组字节大小, 以bytes
为单位
[3]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
print(x)
print('\nx.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)
[[7 1 9]
[2 2 9]
[0 4 9]]
x.ndim: 2
x.shape: (3, 3)
x.size: 9
x.dtype: int64
x.itemsize: 8
x.nbytes: 72
利用列表(list)生成数组¶
利用nd.array
从 Pyhon 列表创建数值:
[4]:
x = np.array([1,2,3,4])
x
[4]:
array([1, 2, 3, 4])
不同于 Python 列表, Numpy 要求数组必须包含同一类型的数据。如果类型不匹配,NumPy 将会向上转换(如果可行)。
[5]:
x = np.array([1.0, 2, 3.0, 4])
x
[5]:
array([1., 2., 3., 4.])
如果希望明确设置数组的数据类型,可以用dtype
变量:
[6]:
x = np.array([1, 2, 3, 4], dtype=np.float32)
x
[6]:
array([1., 2., 3., 4.], dtype=float32)
构建多维数组:
[7]:
x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
x
[7]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
利用Numpy
内置方法创建数值¶
np.zeros()
:创建全 0 数值
[8]:
# 创建一个长度为5的全0数组
x = np.zeros(5)
x
[8]:
array([0., 0., 0., 0., 0.])
np.ones()
:创建全 1 数组
[9]:
# 创建一个3*3的q全1矩阵
x = np.ones((3,3), dtype=float)
x
[9]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
np.eye()
:创建一个单位矩阵
[10]:
# 创建一个3*3的单位矩阵
x = np.eye(3)
x
[10]:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
np.full(shape, fill_value)
:创建一个维数为shape
、值为fill_value
的数组
[11]:
# 创建一个维数为3*3、值为2.0的浮点数型数组
x = np.full((3,3), fill_value=2.0)
x
[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
的序列数组。
[12]:
# 创建一个从0到10,步长为2的序列数组
x = np.arange(0, 10, 2)
x
[12]:
array([0, 2, 4, 6, 8])
[13]:
# 创建一个从0到10,元素个数为5的序列数组
x = np.linspace(0, 10, 5)
x
[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
均匀分布生成的随机整数组成的数值
[14]:
# 创建一个3×3、由0~1均匀分布随机数组成的数组
x = np.random.random((3, 3))
x
[14]:
array([[0.48575322, 0.72737388, 0.32180274],
[0.68450497, 0.37856702, 0.7614299 ],
[0.83093308, 0.66726084, 0.79841631]])
[15]:
# 创建一个3×3、由均值为0、方差为1的正态分布随机数组成的数组
x = np.random.normal(0, 1, (3, 3))
x
[15]:
array([[-0.04566183, 0.72873581, -1.10870786],
[ 0.32082532, 1.78345795, 0.15090186],
[-0.48690445, -0.11890733, 1.85462935]])
[16]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
x
[16]:
array([[5, 2, 2],
[7, 4, 3],
[6, 0, 5]])
数组操作¶
基本运算¶
数组上的运算与 Python 类似,支持 Python 原生的算术运算符,标准的加、减、乘、除都可以使用。
[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 |
取模(余数)除法运算 |
与许多矩阵语言不同,乘法运算符*
在 Numpy 数组中按元素操作,矩阵运算可以使用@
操作符(在 python 3.5中)或dot
函数执行。
[18]:
A = np.array( [[1,1],
[0,1]] )
B = np.array( [[2,0],
[3,4]] )
# 元素操作
print('A * B =\n',A * B)
# 矩阵运算
print('\nA @ B =\n',A @ B)
# 另一种矩阵运算
print('\nA.dot(B) =\n', A.dot(B))
A * B =
[[2 0]
[0 4]]
A @ B =
[[5 4]
[3 4]]
A.dot(B) =
[[5 4]
[3 4]]
索引与切片¶
[19]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
print(x)
# 索引
print('\nx[1,1] =',x[1,1])
# 切片
print('x[1:,1:] =\n',x[1:,1:])
[[8 0 4]
[0 5 0]
[4 1 9]]
x[1,1] = 5
x[1:,1:] =
[[5 0]
[1 9]]
排序¶
np.sort(a, axis=1):
a
表示要排序的数值,axis=0
表示按列排序(axis=1
表示按行排序)
[20]:
# 创建一个4×6、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (4, 6)))
print('x =\n',x)
# 按列排序
print('\nnp.sort(x, axis=0) =\n',np.sort(x, axis=0))
# 按列排序
print('\nnp.sort(x, axis=1) =\n',np.sort(x, axis=1))
x =
[[1 8 8 9 4 5]
[7 0 4 7 3 5]
[1 5 3 2 0 3]
[8 4 3 2 2 3]]
np.sort(x, axis=0) =
[[1 0 3 2 0 3]
[1 4 3 2 2 3]
[7 5 4 7 3 5]
[8 8 8 9 4 5]]
np.sort(x, axis=1) =
[[1 4 5 8 8 9]
[0 3 4 5 7 7]
[0 1 2 3 3 5]
[2 2 3 3 4 8]]
变形¶
reshape()
方法
[21]:
# 创建一个3×3、由[0,10)均匀分布随机整数组成的数值
x = (np.random.randint(0, 10, (3, 3)))
print('x =\n',x)
print('\n通过变形获得的行向量:\n', x.reshape((1, 9)))
print('通过变形获得的列向量:\n', x.reshape((9, 1)))
x =
[[3 9 2]
[8 2 0]
[8 4 9]]
通过变形获得的行向量:
[[3 9 2 8 2 0 8 4 9]]
通过变形获得的列向量:
[[3]
[9]
[2]
[8]
[2]
[0]
[8]
[4]
[9]]
转置¶
[22]:
x = (np.random.randint(0, 10, (2, 3)))
print('x =\n',x)
print('\nx.T =\n',x.T)
x =
[[3 2 3]
[8 4 9]]
x.T =
[[3 8]
[2 4]
[3 9]]
拼接¶
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, ...]
[23]:
x = np.array([[1,2,3,4],
[1,2,3,4]])
x
[23]:
array([[1, 2, 3, 4],
[1, 2, 3, 4]])
[24]:
# 按垂直方向拼接数组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]]
[25]:
# 按水平方向拼接数值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()
:按竖直方向拆分
一维数组:
[26]:
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])]
二维数组:
[27]:
# 按竖直方向拆分
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([[9, 3, 7]]), array([[1, 9, 0]]), array([[8, 8, 9]])]
通过np.hsplit()方法拆分:
[array([[9, 3, 7]]), array([[1, 9, 0]]), array([[8, 8, 9]])]
[28]:
# 按水平方向拆分
print('通过np.split()方法拆分:\n',np.split(y, 3, axis=1))
print('通过np.hsplit()方法拆分:\n',np.hsplit(y, 3))
通过np.split()方法拆分:
[array([[9],
[1],
[8]]), array([[3],
[9],
[8]]), array([[7],
[0],
[9]])]
通过np.hsplit()方法拆分:
[array([[9],
[1],
[8]]), array([[3],
[9],
[8]]), array([[7],
[0],
[9]])]
通用函数¶
Numpy 提供熟悉的数学函数,例如sin
,cos
和exp
等,在 NumPy 中,这些被称为“通用函数”(ufunc
)。
[29]:
x = np.arange(3)
print('x =',x)
print('np.exp(x) =',np.exp(x))
print('np.sqrt(x) =',np.sqrt(x))
print('np.add(x) =',np.add(x,x))
x = [0 1 2]
np.exp(x) = [1. 2.71828183 7.3890561 ]
np.sqrt(x) = [0. 1. 1.41421356]
np.add(x) = [0 2 4]
Numpy 提供了大量的通用函数,详细列表请点击这里
广播¶
广播是一种强有力的机制,通过它 NumPy 可以使不同大小的矩阵在一起进行数学计算。
[30]:
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
[30]:
array([[ 1., 2., 3.],
[11., 12., 13.],
[21., 22., 23.],
[31., 32., 33.]])
想了解更多细节可以点击这里