numpy

基础

from numpy import *

# 多项式的根:x^2 + 2x + 1
result = roots([1,2,1])

# 多元一次方程组
a = [[1,2],[2,-1]]
b = [4,3]
result = linalg.solve(a,b)

# 变形
x = arange(6)
x = x.reshape((2,3))

# 单位矩阵和零矩阵
eye(3)
zeros(9)
ones((2,6))

# 生成等间距样本数据
x = linspace(0,pi,10)

基础如下:

import numpy as np
"""
    备注:本示例中所有的matrix都使用的是array来体现
    实际上python中存在专门的matrix

    # 主要注意matrix和array的区别
    # matrix 使用更加接近matlab的使用方式
    简单示例如下:
    B = np.matrix('1,2;3,4')
    print(B*B)
    # 注意:若使用matrix,则*直接表示矩阵乘法
    # 而元素对应乘积则使用 multiply() 函数
"""
def vector_dot():
    a = np.array([1, 3, 5, 7, 9])
    b = np.array([1, 2, 3, 4, 5])
    # 对应元素相乘
    print(a * b)
    # 对应元素2次幂
    print(a ** 2)
    # dot product
    print(a.dot(b))
    print(type(a))
    print(a.dtype)
    print(a.shape)

def array_matrix_sum():
    d = np.arange(10)
    # 求和:针对数组
    print(d.sum())
    # 求最值
    print(np.min(d))    # 两种方式结果一致
    print(d.max())
    # 累加
    print(d.cumsum())

    x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    # 求和:针对矩阵
    print(x.sum())
    print(np.sum(x, axis=0))  # 列sum
    print(x.sum(axis=1))  # 行sum

def array_matrix_slice():
    # start,stop,num
    d = np.linspace(0, 90, 10)
    print(d)
    # start,stop,num,endpoint=False
    d = np.linspace(0, 100, 10, endpoint=False)
    print(d)
    # 切片
    indices = [1, 3, -1]
    print(d[indices])
    print(d[[1, 3, -1]])  # 外[]表示d的下标,内[]表示下标列表
    print(d[:5])
    # 按照条件 切片
    print(d[d >= 50])
    # 按照条件 查找元素下标
    index = np.where(d >= 50)
    print(index[0])
    print(d[index[0]])

    e = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12],
                  [13, 14, 15, 16]])
    print(e)
    # 矩阵切片方式
    print(e[1:3, 1:3])
    # 选取矩阵中某点
    print(e[3, 2])
    print(e[(3, 2)])
    # 花式索引 --- array[[x],[y]]
    # 坐标对应(1,1),(1,2),(2,1),(2,2)
    # 最终将回去的所有点排成一个一维数组
    print(e[[1, 1, 2, 2], [1, 2, 1, 2]])
    #
    print(e[np.arange(1, 3), 1:3])
    # 返回布尔值,(针对对应元素)
    # 该布尔值也可以用于索引切片
    print(e % 2 == 0)
    print(e[e % 2 == 0])

def array_stack():
    a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
    b = np.array([0, 1, 0, -1])
    c = np.array([0, 1, 0, -1]).reshape(2, 2)
    print('-------------堆叠--------------')
    # 垂直堆叠
    r = np.vstack([a, b])
    print(r)
    # 水平堆叠
    r2 = np.hstack([a, c])
    print(r2)

    print('---------堆叠(方式2)----------')
    # 方式2(以垂直为例)
    b = np.array([[0, 1, 0, -1]])  # concatenate要求dimension一致
    r3 = np.concatenate((a, b), axis=0)
    # r3 = np.concatenate((a, c), axis=1)
    print(r3)

    print('---------堆叠(方式3)----------')
    # 方式3(以水平为例)
    # r4 = np.r_[a, b]  # 垂直堆叠
    r4 = np.c_[a, c]
    print(r4)

    print('-------------扩展--------------')
    x = np.array([1, 2, 3])
    # repeat以元素为单位扩展
    ret = np.repeat(x, 3)
    print(ret)
    # repeat以数组为单位扩展
    ret2 = np.tile(x, 3)
    print(ret2)
    ret3 = np.r_[np.repeat(x, 3), np.tile(x, 3)]
    print(ret3)

def create_matrix():
    a = np.zeros((3, 3))
    print(a)
    b = np.ones((3, 2))
    print(b)
    # 用9填充3*3的矩阵
    c = np.full((3, 3), 9)
    print(c)
    # 用6填充类似b的矩阵
    d = np.full_like(b, 6)
    print(d)
    e = np.eye(3)
    print(e)
    r = np.random.random((2, 2))
    print(r)

def dot_product():
    # 针对 1 dimension
    # 此时dot作用类似于inner(内积)
    # 作用式:两向量数量积
    v = np.array([9, 10])
    w = np.array([11, 12])
    print(v.dot(w))         # Two different ways to express
    print(np.dot(v, w))     # ret = 219

    # 针对 2 dimension
    # 作用是:矩阵乘法
    x = np.array([[1, 2], [3, 4]])
    y = np.array([[5, 6], [7, 8]])
    print(np.dot(x, y))  # dot for 2d -> Matrix / vector product
    # ret = [[19,22],[43,50]]

    # 针对 矩阵
    # 作用是:矩阵乘法
    x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    print(x)
    y = np.eye(3)
    y[(1, 0)] = 2   # 用矩阵描述 矩阵消元法(高斯消元法)
    print(y)
    print(np.dot(y, x))

def matrix_transpose():
    x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    print(x.T)
    # @attention 1d   .T无效
    y = np.array([1, 2, 3])
    print(y.T)

    # 翻转行&列的方式
    print(x[::-1])          # 翻转行
    print(x[:, ::-1])       # 翻转列

def broadcasting(mode=2):
    """
        默认表示经典用法。其他表示常规用法
    """
    x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
    v = np.array([1, 0, -1])
    if mode == 0:
        """
            当数据大时,效率低下
        """
        y = np.empty_like(x)
        for i in range(4):
            y[i, :] = x[i, :] + v
    elif mode == 1:
        vv = np.tile(v, (4, 1))
        y = x + vv
    elif mode == 2:
        """
            广播
        """
        y = x + v
    else:
        y = None
    print(y)

    """
        广播应用2
    """
    a = np.array([1, 2, 3])
    b = np.array([4, 5])
    c = a.reshape((3, 1))
    print(c)
    print(c * b)

def linalg_demo():
    # 资料链接
    # https://www.numpy.org.cn/article/basics/numpy_matrices_vectors.html

    print('----- 解线性方程组 -----')
    A = np.array([[2, 1, -2], [3, 0, 1], [1, 1, -1]])
    b = np.transpose(np.array([[-3, 5, -2]]))
    x = np.linalg.solve(A, b)
    print(x)
    # 查看一些结果,看是否正确
    print(A.dot(x))

    print('----- 求矩阵的逆 -----')
    C = np.linalg.inv(A)
    # 使用round的目的是,让特别小的数,例如1.11e-16显示为0
    print(C)
    print(np.round(C, 6))
    ret = C.dot(A)
    print(np.round(ret, 6))

    print('----- 计算行列式 -----')
    # 方式1
    # D = np.array([[3, 4], [5, 6]])
    # E = np.asmatrix(D)
    # 方式2
    E = np.mat('3,4; 5,6')
    print(E)
    ret = np.linalg.det(E)
    print(np.round(ret, 6))

def float_random_demo():
    a = np.random.random((10, 10))
    np.set_printoptions(precision=3)  # 显示精度3位小数
    np.set_printoptions(threshold=3)  # 最多显示6项,其他项使用省略号
    # np.set_printoptions(threshold=np.nan)   # 显示所有项目
    print(a)

def uniformization():
    value = np.random.randint(5, 10, size=16).reshape(4, 4)
    print(value)
    v_max, v_min = value.max(), value.min()
    # 归一化处理
    uniform_value = (value - v_min) / (v_max - v_min)
    print(uniform_value)

if __name__ == "__main__":
    # vector_dot()
    # array_matrix_sum()
    # array_matrix_slice()
    # array_stack()
    # create_matrix()
    # dot_product()
    # matrix_transpose()
    # broadcasting(0)
    # linalg_demo()
    # float_random_demo()
    uniformization()

点乘

from scipy.spatial.distance import pdist
import numpy as np

def get_module(x):
    """
        x为需要求长度的向量
        欧拉距离/欧式距离(Euclidean Distance)
    """
    return np.sqrt(np.sum(np.square(x)))

def get_angle(x, y):
    """
        一维数据,dot点乘,对数学而言即为求取其数量积
    """
    return np.arccos(np.dot(x, y)/(get_module(x)*get_module(y)))

def get_mudule_len_by_dot():
    print('----- 通过数量积求模长 ----- ')
    # --------------------------------
    # 纯numpy(数学)方式
    OA = np.array([3, 0])
    OB = np.array([0, 4])
    AB = OB - OA  # 指向被减数
    # 长度
    d = get_module(AB)
    print('mlen = ', d)

    # -------------------------------
    # numpy + scipy方式
    xy = np.vstack([OA, OB])
    print(xy)
    dist = pdist(xy)
    print('mlen = ', dist[0])

def get_angle_by_cross():
    """
        已知M(1,1,1),A(2,2,1),B(2,1,2)
        求角度AMB
    """
    print('----- 通过向量积求角度 ----- ')
    M = np.array([1, 1, 1])
    A = np.array([2, 2, 1])
    B = np.array([2, 1, 2])
    MA = A - M
    MB = B - M
    angle = get_angle(MA, MB)
    print(angle)
    if angle - np.pi/3 < 0.0001:
        print('数量积结果正确')

def get_triangle_area_by_cross():
    """
        已知三角形三点坐标,A,B,C坐标点。
        求三角形面积
    """
    print('----- 通过向量积求三角形面积 ----- ')
    A = np.array([1, 2, 3])
    B = np.array([3, 4, 5])
    C = np.array([2, 4, 7])
    AB = B - A
    AC = C - A
    # 面积
    AB_AC = 1/2 * np.cross(AB, AC)
    S = get_module(AB_AC)
    print(S)
    if S - np.sqrt(14) < 0.0001:
        print('向量积结果正确')

if __name__ == "__main__":
    get_mudule_len_by_dot()
    get_angle_by_cross()
    get_triangle_area_by_cross()

叉乘

import numpy as np

def coor_trans(point, theta):
	"""
		coordinate transformation (坐标转换)

		theta方向:以顺时针旋转为正
	"""
	point = np.transpose(point)
	k = np.array([[np.cos(theta), np.sin(theta)],
				  [-np.sin(theta), np.cos(theta)]])
	print(point)
	# return np.dot(k, point)
	return np.round(np.dot(k, point),6)


if __name__ == "__main__":
	point = np.array([[1,0],[1,2],[2,0],[1,0]])
	print(point)
	point_trans = coor_trans(point, np.pi / 2)
	print(point_trans)

矩阵变换

import numpy as np
import scipy.linalg

def matrix_transform():
    """
        目的是通过矩阵乘法实现变换 ------ 旋转,翻转
        **直接**进行切片操作的此处就不介绍了
    """
    # A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    A = np.arange(1, 10).reshape(3, 3)
    print('----- 原始矩阵 -----\n', A)

    B = np.eye(3)[[2, 1, 0]]
    # C = np.transpose(A)
    C = A.T

    print('----- 上下翻转 ----')
    A1 = B.dot(A)       # 左乘
    print(A1)
    print('----- 左右翻转 ----')
    A2 = A.dot(B)       # 右乘
    print(A2)

    print('----- 旋转180° ----')
    print(np.dot(A1, B))    # rotate180 = filpud + filplr
    print(np.dot(B, A2))    # rotate180 = filplr + filpud

    print('----- 旋转90°(以顺时针为正) ----')
    print(np.dot(C, B))     # rotate90 = transpose + filpud
    print('----- 旋转-90°(以顺时针为正) ----')
    print(np.dot(B, C))     # rotate-90 = transpose + filplr


def matrix_decomposition_lu():
    """
        https://baike.baidu.com/item/lu%E5%88%86%E8%A7%A3/764245?fr=aladdin
        scipy采用'列主元三角分解': A=PLU
        手动计算(高斯消元法): A=LU
    """
    A = np.matrix('2,3; 5,4')
    b = np.matrix('4,3').T

    print('----- LU分解 (返PLU参数)-----')
    p, l, u = scipy.linalg.lu(A)
    print(p)
    print(l)
    print(u)

    print('----- Ax=b (A=PLU) 求解x -----')
    y = np.linalg.solve(np.dot(p, l), b)
    x = np.linalg.solve(u, y)
    print(x)

    print('----- 直接解方程 -----')
    x = np.linalg.solve(A, b)
    print(x)

    """
    # 这个L相当于是上述的PL,形式很怪,此处不采用
    print('----- LU分解 (返LU参数)-----')
    l, u = scipy.linalg.lu(A, permute_l=True)
    print(l)
    print(u)
    """


if __name__ == "__main__":
    # matrix_transform()
    matrix_decomposition_lu()

卷积

import numpy as np

'''
	py卷积计算
'''
a = np.array([1,2])
b = np.array([3,4])
print(a)
print(b)
ret = np.convolve(a,b)
print(ret)

'''
	系数向量内积
'''
c = np.array([[2,1,0,],[0,2,1],[0,0,2]])
d = np.array([0,3,4])
print(c)
print(d)
ret = c.dot(d)
# print(ret)


def lsl(lst,k,cnt):
	temp = np.concatenate((lst[-k:],lst[:-k]),axis=0)
	z = np.zeros(cnt)
	z[k:] = temp[k:]
	return z

def conv(a,b):
	'''
		将卷积转换为矩阵运算
	'''
	l_a = len(a)
	l_b = len(b)
	item_cnt = len(a) + len(b) - 1
	data = np.zeros((item_cnt,item_cnt))
	data2 = np.zeros(item_cnt)
	data2[-l_b:] = b[-l_b:]
	a = a[::-1]
	for i in range(item_cnt):
		data[i][:l_a] = a
		data[i][:] = lsl(data[i],i,item_cnt)
	return np.dot(data,data2.transpose())


ret = conv(a,b)
print(ret)

最小二乘法

# -*- coding: utf-8 -*-
"""
Created on Sun Nov 17 14:12:55 2019

@author: Administrator
"""

import matplotlib.pyplot as plt
import numpy as np
x = np.array([25,27,31,33,35])
y = np.array([110,115,155,160,180])
# result = (7.2,-73)
X = np.mat([[25,1],[27,1],[31,1],[33,1],[35,1]])
Y = np.mat(y).T
"""
    最小二乘法的矩阵形式
"""
X_T = X.transpose()
A = np.dot(np.dot(np.linalg.inv(np.dot(X_T,X)),X_T),Y)

a = A[0,0]
b = A[1,0]
y2 = a*x + b
plt.plot(x,y2)
plt.scatter(x,y)
plt.show()

梯度下降法

# -*- coding: utf-8 -*-
"""
Created on Mon Nov 18 20:46:20 2019

@author: Administrator
"""

import matplotlib.pyplot as plt
import numpy as np

def cost_function(X,y,theta):
    m = len(y)
    y_mat = y.reshape(m,1)
    J = 1/(2*m) * np.sum(np.power((X@theta - y_mat),2))
    return J

def gradient_descent(X,y,theta,alpha,num_iters):
    J_history = np.zeros((num_iters,1))
    m = len(y)
    y_mat = y.reshape(m,1)
    for n_iter in range(num_iters):
        theta = theta - alpha * 1 / m * X.T @ (X @ theta - y_mat)
        J_history[n_iter, 0] = cost_function(X,y,theta)
    return J_history, theta

"""
the result of least square = 
[[  7.20930233]
 [-73.72093023]]
"""
x = np.array([25,27,31,33,35])
y = np.array([110, 115, 155, 160, 180])
m = len(x)
X = np.hstack((x.reshape(m, 1), np.ones((m, 1))))

# initial value = (0,0)
theta = np.array([0, 0]).reshape(2, 1)
# if alpha >= 0.0022 ---> overflow (@.@)
alpha = 0.0021

J,theta = gradient_descent(X,y,theta,alpha,400000)
print(theta)