Numpy 矩阵计算
列表元素
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
n = 10
l = [i for i in range(n)]
l # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l * 2
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
a = []
for e in l:
a.append(2 * e)
a # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
效率比较
当 n 值比较大的时候,非常耗时;
使用 for 循环效率远低于 生成表达式:(基本快一倍的时间) ;numpy 的计算则更快。
n = 1000000
l = [i for i in range(n)]
%%time
a = []
for e in l:
a.append(2 * e)
# CPU times: user 147 ms, sys: 15.2 ms, total: 163 ms
# Wall time: 161 ms
%%time
a = [2 * e for e in l]
# CPU times: user 72.2 ms, sys: 20.5 ms, total: 92.7 ms
# Wall time: 91 ms
l1 = np.arange(n)
%%time
a = np.array(2*e for e in l1)
# CPU times: user 12.5 ms, sys: 5.32 ms, total: 17.8 ms
# Wall time: 17.7 ms
numpy 中将每个数组看做向量或矩阵,这种方式也称作 Universal Functions,支持所有运算符运算。
%%time
a = 2 * l1
# CPU times: user 3.58 ms, sys: 4.12 ms, total: 7.7 ms
# Wall time: 5.4 ms
l1 = np.arange(5)
l1 # array([0, 1, 2, 3, 4])
a = 2 * l1
a # array([0, 2, 4, 6, 8])
Universal Functions
基本运算
x + 1
'''
array([[ 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16]])
'''
x * 2
'''
array([[ 2, 4, 6, 8, 10],
[12, 14, 16, 18, 20],
[22, 24, 26, 28, 30]])
'''
# 保留浮点数除法
x / 2
'''
array([[0.5, 1. , 1.5, 2. , 2.5],
[3. , 3.5, 4. , 4.5, 5. ],
[5.5, 6. , 6.5, 7. , 7.5]])
'''
# 整数除法
x // 2
'''
array([[0, 1, 1, 2, 2],
[3, 3, 4, 4, 5],
[5, 6, 6, 7, 7]])
'''
# 幂运算
x ** 2
'''
array([[ 1, 4, 9, 16, 25],
[ 36, 49, 64, 81, 100],
[121, 144, 169, 196, 225]])
'''
# 取余
x % 2
'''
array([[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 1]])
'''
特殊运算
# 绝对值
np.abs(x)
'''
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]])
'''
np.sin(x)
'''
array([[ 0.84147098, 0.90929743, 0.14112001, -0.7568025 , -0.95892427],
[-0.2794155 , 0.6569866 , 0.98935825, 0.41211849, -0.54402111],
[-0.99999021, -0.53657292, 0.42016704, 0.99060736, 0.65028784]])
'''
np.exp(x)
'''
array([[2.71828183e+00, 7.38905610e+00, 2.00855369e+01, 5.45981500e+01,
1.48413159e+02],
[4.03428793e+02, 1.09663316e+03, 2.98095799e+03, 8.10308393e+03,
2.20264658e+04],
[5.98741417e+04, 1.62754791e+05, 4.42413392e+05, 1.20260428e+06,
3.26901737e+06]])
'''
np.power(3, x) # 3 的 x 次方
'''
array([[ 3, 9, 27, 81, 243],
[ 729, 2187, 6561, 19683, 59049],
[ 177147, 531441, 1594323, 4782969, 14348907]])
'''
np.log(x) # 对矩阵的元素取 log 值
'''
array([[0. , 0.69314718, 1.09861229, 1.38629436, 1.60943791],
[1.79175947, 1.94591015, 2.07944154, 2.19722458, 2.30258509],
[2.39789527, 2.48490665, 2.56494936, 2.63905733, 2.7080502 ]])
'''
# 以2为底数
np.log2(x)
'''
array([[0. , 1. , 1.5849625 , 2. , 2.32192809],
[2.5849625 , 2.80735492, 3. , 3.169925 , 3.32192809],
[3.45943162, 3.5849625 , 3.70043972, 3.80735492, 3.9068906 ]])
'''
# 以10为底数
np.log10(x)
'''
array([[0. , 0.30103 , 0.47712125, 0.60205999, 0.69897 ],
[0.77815125, 0.84509804, 0.90308999, 0.95424251, 1. ],
[1.04139269, 1.07918125, 1.11394335, 1.14612804, 1.17609126]])
'''
矩阵之间的计算
对两个计算的矩阵的尺寸有要求
a = np.arange(4).reshape(2, 2)
a
'''
array([[0, 1],
[2, 3]])
'''
b = np.full((2, 2), 10)
b
'''
array([[10, 10],
[10, 10]])
'''
a + b
'''
array([[10, 11],
[12, 13]])
'''
a * b # 对应元素相乘;非矩阵乘法
'''
array([[ 0, 10],
[20, 30]])
'''
a / b
'''
array([[0. , 0.1],
[0.2, 0.3]])
'''
# 矩阵乘法
np.dot(a, b)
'''
array([[10, 10],
[50, 50]])
'''
a.dot(b)
'''
array([[10, 10],
[50, 50]])
'''
c = np.arange(4).reshape(2, 2)
c
'''
array([[0, 1],
[2, 3]])
'''
a.dot(c)
'''
array([[ 2, 3],
[ 6, 11]])
'''
np.dot(a, c)
'''
array([[ 2, 3],
[ 6, 11]])
'''
# 转置
a.T
'''
array([[0, 2],
[1, 3]])
'''
向量和矩阵的运算
v = np.array([1, 2])
v + a
'''
array([[1, 3],
[3, 5]])
'''
a
'''
array([[0, 1],
[2, 3]])
'''
v2 = np.array([1, 2, 3])
a + v2 # 报错
'''
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-48-a196cec3120e> in <module>
1 v2 = np.array([1, 2, 3])
----> 2 a + v2
ValueError: operands could not be broadcast together with shapes (2,2) (3,)
'''
np.vstack([v] * a.shape[0]) # 实际是将这个矩阵 和 a 做处理
'''
array([[1, 2],
[1, 2]])
'''
a.shape # (2, 2)
a.size # 4
a.shape[0] # 2
np.vstack([v] * a.shape[0]) + a
'''
array([[1, 3],
[3, 5]])
'''
## tile 函数
np.tile(v, (3, 2))
'''
array([[1, 2, 1, 2],
[1, 2, 1, 2],
[1, 2, 1, 2]])
'''
v # array([1, 2])
a
'''
array([[0, 1],
[2, 3]])
'''
v * a
'''
array([[0, 2],
[2, 6]])
'''
a * v
'''
array([[0, 2],
[2, 6]])
'''
v.dot(a)
'''
array([4, 7])
'''
a.dot(v)
'''
array([2, 8])
'''
矩阵的逆
方阵才可能存在逆矩阵;非方阵可以求伪逆矩阵。
a
'''
array([[0, 1],
[2, 3]])
'''
invA = np.linalg.inv(a)
invA
'''
array([[-1.5, 0.5],
[ 1. , 0. ]])
'''
a.dot(invA)
'''
array([[1., 0.],
[0., 1.]])
'''
invA.dot(a)
'''
array([[1., 0.],
[0., 1.]])
'''
X = np.arange(16).reshape((2,8))
X
'''
array([[ 0, 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14, 15]])
'''
np.linalg.inv(X)
'''
---------------------------------------------------------------------------
LinAlgError Traceback (most recent call last)
<ipython-input-71-47889a8f1529> in <module>
----> 1 np.linalg.inv(X)
<__array_function__ internals> in inv(*args, **kwargs)
~/opt/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py in inv(a)
539 a, wrap = _makearray(a)
540 _assert_stacked_2d(a)
--> 541 _assert_stacked_square(a)
542 t, result_t = _commonType(a)
543
~/opt/anaconda3/lib/python3.7/site-packages/numpy/linalg/linalg.py in _assert_stacked_square(*arrays)
202 m, n = a.shape[-2:]
203 if m != n:
--> 204 raise LinAlgError('Last 2 dimensions of the array must be square')
205
206 def _assert_finite(*arrays):
LinAlgError: Last 2 dimensions of the array must be square
'''
## 伪逆矩阵
pinvX = np.linalg.pinv(X)
pinvX
'''
array([[-1.35416667e-01, 5.20833333e-02],
[-1.01190476e-01, 4.16666667e-02],
[-6.69642857e-02, 3.12500000e-02],
[-3.27380952e-02, 2.08333333e-02],
[ 1.48809524e-03, 1.04166667e-02],
[ 3.57142857e-02, -7.30583920e-18],
[ 6.99404762e-02, -1.04166667e-02],
[ 1.04166667e-01, -2.08333333e-02]])
'''
pinvX.shape # (8, 2)
pinvX.dot(X)
'''
array([[ 4.16666667e-01, 3.33333333e-01, 2.50000000e-01,
1.66666667e-01, 8.33333333e-02, 4.78783679e-16,
-8.33333333e-02, -1.66666667e-01],
[ 3.33333333e-01, 2.73809524e-01, 2.14285714e-01,
1.54761905e-01, 9.52380952e-02, 3.57142857e-02,
-2.38095238e-02, -8.33333333e-02],
[ 2.50000000e-01, 2.14285714e-01, 1.78571429e-01,
1.42857143e-01, 1.07142857e-01, 7.14285714e-02,
3.57142857e-02, 2.84494650e-16],
[ 1.66666667e-01, 1.54761905e-01, 1.42857143e-01,
1.30952381e-01, 1.19047619e-01, 1.07142857e-01,
9.52380952e-02, 8.33333333e-02],
[ 8.33333333e-02, 9.52380952e-02, 1.07142857e-01,
1.19047619e-01, 1.30952381e-01, 1.42857143e-01,
1.54761905e-01, 1.66666667e-01],
[-5.84467136e-17, 3.57142857e-02, 7.14285714e-02,
1.07142857e-01, 1.42857143e-01, 1.78571429e-01,
2.14285714e-01, 2.50000000e-01],
[-8.33333333e-02, -2.38095238e-02, 3.57142857e-02,
9.52380952e-02, 1.54761905e-01, 2.14285714e-01,
2.73809524e-01, 3.33333333e-01],
[-1.66666667e-01, -8.33333333e-02, -2.22044605e-16,
8.33333333e-02, 1.66666667e-01, 2.50000000e-01,
3.33333333e-01, 4.16666667e-01]])
'''
X.dot(pinvX) # 计算结果不完全是0,是计算机的浮点误差造成的
'''
array([[ 1.00000000e+00, -2.77555756e-16],
[ 1.69309011e-15, 1.00000000e+00]])
'''