Python | numpy matplotlib scipy练习笔记

  • 代码主要来源:邹博机器学习教程第四课python基础

Numpy 练习

np.arange(9)
生成的是列向量,并不是直观看到的行向量

# coding:utf-8

import numpy as np
import matplotlib as mpl
import scipy as sp
import math
import time

def residual(t, x, y):
    return y - (t[0] * x**2 + t[1] * x + t[2])


def f(x):
    y = np.ones_like(x)
    i = x > 0
    y[i] = np.power(x[i], x[i])
    i = x < 0
    y[i] = n.power(-x[i], -x[i])
    return y


### 得到二维数组
# arange左闭右开,步长为10 reshape变换为任意行数,1列的列向量
# arange(6)为[0 1 2 3 4 5]
#广播机制:行向量与列向量相加,各自相加,形成矩阵
# a = np.arange(0, 60, 10).reshape((-1, 1)) + np.arange(6)
# print(a)
# b = np.arange(0, 60, 10).reshape(-1, 1) + np.arange(6)
# print(b)
# 结果:(a b相同)
# [[ 0  1  2  3  4  5]
#  [10 11 12 13 14 15]
#  [20 21 22 23 24 25]
#  [30 31 32 33 34 35]
#  [40 41 42 43 44 45]
#  [50 51 52 53 54 55]]

### python中的list,元素的本质是对象,,对于us沪指计算比较浪费内存和CPU,计算较慢
### 所以使用numpy中的ndarray 加速计算
## 通过array传递list
# L = [1, 2, 3, 4, 5, 6]
# print(L)
# a = np.array(L)
# print(a)
# print(type(L), type(a))
# 传递多层嵌套的list,则是多维数组
# b = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# print(b)
# 数组大小 通过其shape属性获得
# print(a.shape, b.shape)
# 强制修改shape 但是同时也改变了其原有结构
# 注:从(3,4)改为(4,3)并不是对数组进行转置,
# 而只是改变每个轴的大小,数组元素在内存中的位置并没有改变
# 当行或列为 -1 时表示不需要顾及它,按照另一个值进行修改shape,例如b.shape = -1, 5
# b.shape = 4, 3
# print(b)
# 使用reshape可以改变数组的尺寸,也可以创建改变了尺寸的新数组c,原数组的shape不变
# b = b.reshape(4, -1)
# c = b.reshape(6, -1)
# print(b)
# print(c)
# 这样得到的b和c共享内存,修改任意一个,另一个将改变
# b[0][1] = 20
# print(b)
# print(c)
# dtype属性:数组的元素类型
# print(a.dtype, b.dtype)
#创建数组时通过dtype指定元素类型
# d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype = np.float)
# e = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.complex)
# f = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.int)
# print(d)
# print(e)
# print(f)
# astype 更改元素类型,安全的转换
# g  = d.astype(np.int)
# 但不要强制仅修改元素类型,如下面这句,将会以int来解释单精度float类型
# d.dtype = np.int
# print(d)
# 结果:
# [1, 2, 3, 4, 5, 6]
# [1 2 3 4 5 6]
# <class 'list'> <class 'numpy.ndarray'>
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
# (6,) (3, 4)
# [[ 1  2  3]
# [ 4  5  6]
# [ 7  8  9]
# [10 11 12]]

# [[ 1  2  3]
#  [ 4  5  6]
#  [ 7  8  9]
#  [10 11 12]]
# [[ 1  2]
#  [ 3  4]
#  [ 5  6]
#  [ 7  8]
#  [ 9 10]
#  [11 12]]

# [[ 1 20  3]
#  [ 4  5  6]
#  [ 7  8  9]
#  [10 11 12]]
# [[ 1 20]
#  [ 3  4]
#  [ 5  6]
#  [ 7  8]
#  [ 9 10]
#  [11 12]]

# int32 int32

# [[ 1.  2.  3.  4.]
#  [ 5.  6.  7.  8.]
#  [ 9. 10. 11. 12.]]
# [[ 1.+0.j  2.+0.j  3.+0.j  4.+0.j]
#  [ 5.+0.j  6.+0.j  7.+0.j  8.+0.j]
#  [ 9.+0.j 10.+0.j 11.+0.j 12.+0.j]]
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]

# [[         0 1072693248          0 1073741824          0 1074266112
#            0 1074790400]
#  [         0 1075052544          0 1075314688          0 1075576832
#            0 1075838976]
#  [         0 1075970048          0 1076101120          0 1076232192
#            0 1076363264]]

### np.arange(1, 20, 2) 左闭右开,步长为2,
### 和python中的range类似,但是range只能生成整数型,而arange可以生成浮点型
# 延长打印区域长度为100,不换行表示,并且不使用科学计数法显示
# np.set_printoptions(linewidth=100, suppress=True)
# a = np.arange(1, 10, 0.5)
# print(a)
# 结果:
# [1.  1.5 2.  2.5 3.  3.5 4.  4.5 5.  5.5 6.  6.5 7.  7.5 8.  8.5 9.  9.5]

### linspace(1,10,5)函数 创建数组,左右全闭,从1开始到10结束,个数为5
# b = np.linspace(1, 10, 10)
# print(b)
# 通过endpoint关键词指定是否包含终值
# 相当于np.linspace(1, 10, 11)计算后去掉最后一个生成的数值
# c = np.linspace(1, 10, 10, endpoint=False)
# print('c = ', c)
# logspace(1, 5, 4, base=2) 创建等比数列,从2的1次方到2的5次方,取4个数;不标注的话默认底数为10
# d = np.logspace(1, 5, 4, endpoint=True, base=2)
# print(d)
# 结果:
# [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
# c =  [1.  1.9 2.8 3.7 4.6 5.5 6.4 7.3 8.2 9.1]
# [ 2.          5.0396842  12.69920842 32.        ]

### 使用 frombuffer, fromstring, fromfile等函数可以从字节序列创建数组
############## 这里不太懂,不会用 ##########################
# s = 'abcdzzzz'
# g = np.fromstring(s, dtype=np.int8) #转换成对应的ascII
# print(g)
# 结果:
# [ 97  98  99 100 122 122 122 122]

### 3.存取
### 3.1 常规办法:和python中list相同的方法
# a = np.arange(10)
# print(a)
# print(a[0]) #获取某个元素
# 以下均为切片操作
# 对于切片操作,切片数据是原数组的一个视图/引用(不算拷贝)
# 与原数组共享内存空间,可以直接修改元素值
# print(a[3:6]) #左闭右开
# print(a[3:])
# print(a[:4])
# print(a[:]) #所有
# print(a[1:9:2]) #步长为2
# print(a[9:1:-2]) #倒序,步长为2
# print(a[::-1]) #反转 reverse
# a[1:4] = 10, 20, 30 #修改数组
# print(a)
# b = a[2:5]
# print(b)
# b[0] = 200
# print(b)
# print(a)
# 结果:
# [0 1 2 3 4 5 6 7 8 9]
# 0
# [3 4 5]
# [3 4 5 6 7 8 9]
# [0 1 2 3]
# [0 1 2 3 4 5 6 7 8 9]
# [1 3 5 7]
# [9 7 5 3]
# [9 8 7 6 5 4 3 2 1 0]
# [ 0 10 20 30  4  5  6  7  8  9]
# [20 30  4]
# [200  30   4]
# [  0  10 200  30   4   5   6   7   8   9]

### 3.2 整数/布尔数组存取 (索引)
### 3.2.1
### 整数数组存取(索引):当使用整数序列对数组元素进行存取时,
### 将使用整数序列中的每个元素作为下标,整数序列可以是list或ndarray
### 使用整数序列作为下标获得的数组不与原数组共享数据空间
np.set_printoptions(suppress=True)
# a = np.logspace(0, 9, 10, base=2)
# print(a)
# i = np.arange(0, 10, 2)
# print(i)
#利用i取a中的元素
# b = a[i]
# print(b)
# b[2] = 111111
# print(b)
# print(a)
# 结果:
# [  1.   2.   4.   8.  16.  32.  64. 128. 256. 512.]
# [0 2 4 6 8]
# [  1.   4.  16.  64. 256.]
# [     1.      4. 111111.     64.    256.]
# [  1.   2.   4.   8.  16.  32.  64. 128. 256. 512.]

### 3.2.2
### 布尔数组i作为下标存取数组a中的元素(索引)
### 返回数组a中所有在数组b中对应下标为True的元素
### b与a不共享内存空间,不相互影响
a = np.random.rand(10) #生成10个满足[0, 1)中均匀分布的随机数
print(a)
print(a > 0.5) #布尔数组
b = a[a > 0.5]
print(b)
a[a > 0.5] = 0.5
print(a)
print(b)
# 结果:
# [0.59258726 0.86618547 0.35026646 0.44017041 0.51553528 0.00809087
#  0.57875341 0.63426188 0.80243144 0.42357513]
# [ True  True False False  True False  True  True  True False]
# [0.59258726 0.86618547 0.51553528 0.57875341 0.63426188 0.80243144]
# [0.5        0.5        0.35026646 0.44017041 0.5        0.00809087
#  0.5        0.5        0.5        0.42357513]
# [0.59258726 0.86618547 0.51553528 0.57875341 0.63426188 0.80243144]

### 3.3 二维数组的切片
# a = np.arange(0, 60, 10)    # 行向量
# print('a = ', a)
# b = a.reshape((-1, 1))      # 转换成列向量
# print(b)
# c = np.arange(6)
# print(c)
# f = b + c   # 行 + 列
# print(f)
# # 合并上述代码:
# a = np.arange(0, 60, 10).reshape((-1, 1)) + np.arange(6)
# print(a)
# # # 二维数组的切片
# print(a[[0, 1, 2], [2, 3, 4]]) # 第0行第列的数,第1行第3列的······
# print(a[4, [2, 3, 4]]) # 第4行中第2 3 4列的三个数
# print(a[[4], [2, 3, 4]]) # 两种写法均可
# print(a[4:, [2, 3, 4]]) # 第4和第5行中第2 3 4列所有的数
# i = np.array([True, False, True, False, False, True])
# print(a[i])
# print(a[i, 3])
# 结果:
# a =  [ 0 10 20 30 40 50]
# [[ 0]
#  [10]
#  [20]
#  [30]
#  [40]
#  [50]]
# [0 1 2 3 4 5]
# [[ 0  1  2  3  4  5]
#  [10 11 12 13 14 15]
#  [20 21 22 23 24 25]
#  [30 31 32 33 34 35]
#  [40 41 42 43 44 45]
#  [50 51 52 53 54 55]]
# [[ 0  1  2  3  4  5]
#  [10 11 12 13 14 15]
#  [20 21 22 23 24 25]
#  [30 31 32 33 34 35]
#  [40 41 42 43 44 45]
#  [50 51 52 53 54 55]]
# [ 2 13 24]
# [42 43 44]
# [42 43 44]
# [[42 43 44]
#  [52 53 54]]
# [[ 0  1  2  3  4  5]
#  [20 21 22 23 24 25]
#  [50 51 52 53 54 55]]
# [ 3 23 53]

### 4.1 numpy 与 python数学库的计算时间比较
for j in np.logspace(0, 7, 8): # [1 10 100 ·····]
    x = np.linspace(0, 10, j) # 计算j次
    start = time.clock()
    y = np.sin(x) # 其中x为数组,直接计算完所有的元素,不用for循环遍历
    t1 = time.clock() - start

    x = x.tolist() #将矩阵/数组x转换成列表
    start = time.clock()
    for i, t in enumerate(x):
        x[i] = math.sin(t)
    t2 = time.clock() - start
    print(j, ": ", t1, t2, t2 / t1)
# enumerate()用法,给每一个元素写入一个下标,一般用在for循环中
x = np.linspace(0, 10, 9)
x = x.tolist()
y = list(enumerate(x))
print(y)
# 结果:(基本维持在18-20倍)
# 1.0 :  4.091326592190885e-06 4.383564205918805e-06 1.0714285714285714
# 10.0 :  2.0456632960954424e-06 3.7990889784629664e-06 1.857142857142858
# 100.0 :  2.6301385235512928e-06 2.2210058643321935e-05 8.44444444444441
# 1000.0 :  1.2273979776572654e-05 0.00021888597268221232 17.833333333333332
# 10000.0 :  0.00012303203537945438 0.0022028871322810634 17.90498812351545
# 100000.0 :  0.0011800554842333424 0.022297437689826595 18.89524517087667
# 1000000.0 :  0.013207678952433362 0.2944746926610076 22.295718552937274
# 10000000.0 :  0.1402936345095216 2.4657317790578435 17.575507168791017
# [(0, 0.0), (1, 1.25), (2, 2.5), (3, 3.75), (4, 5.0), (5, 6.25), (6, 7.5), (7, 8.75), (8, 10.0)]

### 4.2 元素去重
# 4.2.1 一维数组去重
a = np.array([1, 2, 3, 4, 5, 5, 7, 3, 2, 2, 8, 8])
print('去重前:', a)
b = np.unique(a)
print('去重后:', b)
# 4.2.2 二维数组去重
c = np.array(((1, 2), (3, 4), (5, 6), (1, 3), (3, 4), (7, 6)))
print('去重前:', c)
# 方法一:利用set,set是无序不重复集合(推荐)
s = set() #创建空集合
for t in c:
    s.add(tuple(t)) #将数组转为元祖tuple,保证不被修改;再把元祖加入到集合中,完成去重
g = np.array(list(s)) # 将集合转换为列表,最后转为二维数组
print('去重后:', g)
# 合起来写
print('方法一去重后:', np.array(list(set(tuple(t) for t in c))))
# 方法二:转换为虚数
r, i = np.split(c, (1, ), axis=1)
print(r)
print(i)
x = r + i * 1j
# x = c[:, 0] + c[:, 1] * 1j
print('转换成虚数:', x) # 变成一维数组,可使用np.unique()
print('虚数去重后:', np.unique(x))
print(np.unique(x, return_index=True, return_counts=True))
# return_index=True表示返回另一个参数,这个参数也是一个数组,
# array([0, 3, 1, 2, 5]表示去重后的每个元素在去重前的数组中的位置/下标
# return_counts=True表示返回各元素出现的频次
idx = np.unique(x, return_index=True)[1]
# 第[1]列的数组正是return_index=True返回的内容:在c中的位置/下标
print('二维数组去重:\n', c[idx]) #提取这些下标所在的元素
# 结果:
# 去重前: [1 2 3 4 5 5 7 3 2 2 8 8]
# 去重后: [1 2 3 4 5 7 8]
# 去重前: [[1 2]
#  [3 4]
#  [5 6]
#  [1 3]
#  [3 4]
#  [7 6]]
# 去重后: [[1 2]
#  [1 3]
#  [5 6]
#  [7 6]
#  [3 4]]
# 方法一去重后: [[1 2]
#  [1 3]
#  [5 6]
#  [7 6]
#  [3 4]]
# [[1]
#  [3]
#  [5]
#  [1]
#  [3]
#  [7]]
# [[2]
#  [4]
#  [6]
#  [3]
#  [4]
#  [6]]
# 转换成虚数: [[1.+2.j]
#  [3.+4.j]
#  [5.+6.j]
#  [1.+3.j]
#  [3.+4.j]
#  [7.+6.j]]
# 虚数去重后: [1.+2.j 1.+3.j 3.+4.j 5.+6.j 7.+6.j]
# (array([1.+2.j, 1.+3.j, 3.+4.j, 5.+6.j, 7.+6.j]), array([0, 3, 1, 2, 5], dtype=int64), array([1, 1, 2, 1, 1], dtype=int64))
# 二维数组去重:
#  [[1 2]
#  [1 3]
#  [3 4]
#  [5 6]
#  [7 6]]

### 关于np.split()函数
x = np.arange(9) #9行1列的列向量
print(x, np.shape(x))
y = np.split(x, 3) # 平均分成三份,不能平均的话则会报错
print(y)
y = np.split(x, 3, axis=0) # 平均分成三份,不能平均的话则会报错,axis默认为0
print(y)
# 不均等分割 np.array_split()
y = np.array_split(x, 4, axis=0) #第0项分割出来的元素最多,剩下的均等分
print('不均等分割:',y)
y = np.split(x, (3,)) # 在第3行之前进行切割,切割成2份
print(y)
y = np.split(x, [3, 5, 7, 8]) #都是开区间进行分割,在第3行,第5行···前进行切割
print(y)
k = np.arange(1, 3, 0.5).reshape(-1, 1)
print(k)
m = x + k
print(m)
m1 = np.split(m, 3, axis=1) # axis=0表示横着切,axis=1表示竖着切
print(m1)
m0 = np.split(m, 2, axis=0)
print(m0)
a, b = np.split(m, (4,), axis=1)
print('a = ',a)
print('b = ',b)
# 结果:
# [0 1 2 3 4 5 6 7 8] (9,)
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
# 不均等分割: [array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7, 8])]
# [array([0, 1, 2]), array([3, 4, 5, 6, 7, 8])]
# [array([0, 1, 2]), array([3, 4]), array([5, 6]), array([7]), array([8])]
# [[1. ]
#  [1.5]
#  [2. ]
#  [2.5]]
# [[ 1.   2.   3.   4.   5.   6.   7.   8.   9. ]
#  [ 1.5  2.5  3.5  4.5  5.5  6.5  7.5  8.5  9.5]
#  [ 2.   3.   4.   5.   6.   7.   8.   9.  10. ]
#  [ 2.5  3.5  4.5  5.5  6.5  7.5  8.5  9.5 10.5]]
# [array([[1. , 2. , 3. ],
#        [1.5, 2.5, 3.5],
#        [2. , 3. , 4. ],
#        [2.5, 3.5, 4.5]]), array([[4. , 5. , 6. ],
#        [4.5, 5.5, 6.5],
#        [5. , 6. , 7. ],
#        [5.5, 6.5, 7.5]]), array([[ 7. ,  8. ,  9. ],
#        [ 7.5,  8.5,  9.5],
#        [ 8. ,  9. , 10. ],
#        [ 8.5,  9.5, 10.5]])]
# [array([[1. , 2. , 3. , 4. , 5. , 6. , 7. , 8. , 9. ],
#        [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]]), array([[ 2. ,  3. ,  4. ,  5. ,  6. ,  7. ,  8. ,  9. , 10. ],
#        [ 2.5,  3.5,  4.5,  5.5,  6.5,  7.5,  8.5,  9.5, 10.5]])]
# a =  [[1.  2.  3.  4. ]
#  [1.5 2.5 3.5 4.5]
#  [2.  3.  4.  5. ]
#  [2.5 3.5 4.5 5.5]]
# b =  [[ 5.   6.   7.   8.   9. ]
#  [ 5.5  6.5  7.5  8.5  9.5]
#  [ 6.   7.   8.   9.  10. ]
#  [ 6.5  7.5  8.5  9.5 10.5]]

### stack增加维度/堆叠和axis轴
a = np.arange(1, 7).reshape((2, 3))
b = np.arange(11, 17).reshape((2, 3))
c = np.arange(21, 27).reshape((2, 3))
d = np.arange(31, 37).reshape((2, 3))
print('a = \n', a)
print('b = \n', b)
print('c = \n', c)
print('d = \n', d)
s = np.stack((a, b, c, d), axis=0) # 在第0个位置增加维度,其他位置还是表示行和列
print('axis = 0 ', s.shape, '\n', s) # axis=0 直接堆叠,不切分
s = np.stack((a, b, c, d), axis=1) # 在第1个位置增加维度,其他位置还是表示行和列
print('axis = 1 ', s.shape, '\n', s) # axis=1 把每个数组的同一行拿出来上下按行堆叠在一起组成新的数组块
s = np.stack((a, b, c, d), axis=2) # 在第2个位置增加维度,其他位置还是表示行和列
print('axis = 2 ', s.shape, '\n', s) # axis=2 把每个数组的同一行拿出来左右按列堆叠在一起组成新的数组块,或者说相当于把axis=1得来的新数组块求转置得到新得的数组块
# 结果:
# a = 
#  [[1 2 3]
#  [4 5 6]]
# b = 
#  [[11 12 13]
#  [14 15 16]]
# c = 
#  [[21 22 23]
#  [24 25 26]]
# d = 
#  [[31 32 33]
#  [34 35 36]]
# 4=abcd有4个,2和3表示2行3列
# axis = 0  (4, 2, 3) # 4块(第0个位置为4,在第0个位置增加维度),每块2行3列
#  [[[ 1  2  3]
#   [ 4  5  6]] # 第一块  2行 3列
# 
#  [[11 12 13]
#   [14 15 16]] #  第二块
# 
#  [[21 22 23]
#   [24 25 26]] # 第三块
# 
#  [[31 32 33]
#   [34 35 36]]] # 第四块
# axis = 1  (2, 4, 3) # 2块,每块4行3列(第1个位置为4,在第1个位置增加维度)
#  [[[ 1  2  3]
#   [11 12 13]
#   [21 22 23]
#   [31 32 33]]
# 
#  [[ 4  5  6]
#   [14 15 16]
#   [24 25 26]
#   [34 35 36]]]
# axis = 2  (2, 3, 4) # 2块,每块3行4列(第2个位置为4,在第2个位置增加维度)
#  [[[ 1 11 21 31]
#   [ 2 12 22 32]
#   [ 3 13 23 33]] 
# 
#  [[ 4 14 24 34]
#   [ 5 15 25 35]
#   [ 6 16 26 36]]]

关于np.stack()的理解

Matplotlib 与 Scipy 练习

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import math
import time
import scipy as sp
from scipy import stats
from scipy.stats import norm, poisson
from mpl_toolkits.mplot3d import Axes3D
import scipy.optimize as opt

###### 配置文件的两条语句
# 设置字体font为sans-serif,并且使用仿宋黑体,保证可以正常显示中文标签(u+'内容'表示可以正常显示里面的中文)
mpl.rcParams['font.sans-serif'] = [u'SimHei'] # rc参数可以修改默认的属性
#在matplotlib中的rc配置文件,里面的内容都是以key-value的形式出现的
#所以可以通过mpl.rcParams['font.sans-serif'] = ['SimHei']  这种形式加以配置
mpl.rcParams['axes.unicode_minus'] = False #轴线.负号,False表示正常显示负号



### 5. matplotlib绘图
### 5.1 正态分布概率密度函数
mu = 0
sigma = 1
x = np.linspace(mu - 3 * sigma, mu + 3 * sigma, 51)
y = np.exp(-(x - mu) ** 2 / (2 * sigma ** 2)) / (math.sqrt(2 * math.pi) * sigma)
print(x.shape)
print('x = \n', x)
print(y.shape)
print('y = \n', y)
# figure()窗体函数,新建一个画布/窗体,默认名称为figure1
plt.figure(num=5, figsize=(8, 5), facecolor='w') #figure窗体的背景颜色 w白色,命名为figure5,画布大小8*5
# plot()画图函数,描点x和y并绘图,o表示点,-表示实线
#plt.plot(x, y, 'ro-', linewidth=4) #图像线宽4,‘’内r代表红色线(默认为蓝色),o表示描点(默认不描点),-表示实线(--表示虚线)
plt.plot(x, y, 'go', x, y, 'r-', linewidth=2, markersize=15) # 一个xy设置线相关,另一个xy设置点相关,先设置的先画,后设置的后画;go表示绿色描点
# ;描点大小15
# label()函数,设置XY轴的轴名称以及名称显示的字体大小
plt.xlabel('X轴', fontsize=50)
plt.ylabel('Y', fontsize=15)
# title()标题函数
plt.title(u'高斯分布函数', fontsize=18) # 保证显示中文,不加u可能也显示
plt.grid(True) # 显示背景网格线,默认为黑色实线
# plt.grid(color='r', linestyle='--', linewidth=10)
plt.show() # 显示图像,一张画布可同时显示多个图像,show之前有几个plot就显示几个



### 5.2 损失函数:Logistic损失(-1, 1)/SVM Hinge损失/ 0/1损失
plt.figure(figsize=(10, 10))
x = np.linspace(start=-2, stop=3, num=1001, dtype=np.float)
y_logit = np.log(1 + np.exp(-x)) / np.log(2)
y_boost = np.exp(-x)
y_01 = x < 0 # 返回布尔值,在坐标轴上1 True,0 False
y_hinge = 1.0 - x
y_hinge[y_hinge < 0] = 0
# print(y_hinge[y_hinge < 0]) 打印所有小于0的值
plt.plot(x, y_logit, 'r-', label='Logistic Loss', linewidth=2)
plt.plot(x, y_01, 'g-', label='0/1 Loss', linewidth=2)
plt.plot(x, y_hinge, 'b-', label='Hinge Loss', linewidth=2)
plt.plot(x, y_boost, 'm--', label='Adaboost Loss', linewidth=2)
plt.grid() # True 显示网格线
# plt.legend()图例函数,多图像显示时,legend内显示各图像的线条和名称
plt.legend(loc='upper right') # 图例的location在右上角显示,或者best也行
plt.savefig('1.png') # 保存图像,与代码相同的路径下
plt.show()

### 5.3 x^x
# x ** x       x > 0
# (-x) ** (-x)  x < 0
def f(x):
    y = np.ones_like(x) # zeros_like(x) 把y变成和x形状一样的数组,但是元素全部为0
    i = x > 0
    y[i] = np.power(x[i], x[i]) #np.power(x, n) x的n次方,n可以是数组,但是要和x同shape和dtype
    i = x < 0
    y[i] = np.power(-x[i], -x[i])
    return y

plt.figure(facecolor='w')
x = np.linspace(-1.3, 1.3, 101)
y = f(x)
plt.plot(x, y, 'g-', label='x^x', linewidth=2)
plt.grid()
plt.legend(loc='upper left')
plt.show()


### 5.4 胸形线
x = np.arange(1, 0, -0.001)
y = (- 3 * x * np.log(x) + np.exp(- (40 * (x - 1 / np.e)) ** 4) / 25) / 2
plt.figure(figsize=(5, 7), facecolor='w')
plt.plot(y, x, 'r-', linewidth=2) # 以y的值为横坐标,x的值为纵坐标
plt.grid()
plt.title(u'胸形线', fontsize=20)
plt.show()


### 5.5 心形线
t = np.linspace(0, 2*np.pi, 100)
x = 16 * np.sin(t) ** 3
y = 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t)
plt.figure()
plt.plot(x, y, linewidth=2)
plt.grid()
plt.show()


### 5.6 渐开线/蚊香线
# 默认新建画布
t = np.linspace(0, 50, num=1000)
x = t * np.sin(t) + np.cos(t)
y = np.sin(t) - t * np.cos(t)
plt.plot(x, y, 'r-', linewidth=2)
plt.grid()
plt.show()


### 5.7 Bar 画柱形图
x = np.arange(0, 10, 0.1)
y = np.sin(x)
# 画柱形图,width柱的宽度,linewidth给柱描边线的线宽,facecolor柱色,edgecolor描边色
plt.bar(x, y, width=0.04, linewidth=1, facecolor='b', edgecolor='r')
# 画线形图
plt.plot(x, y, 'g--', linewidth=2)
plt.title(u'Sin曲线')
plt.xticks(ratation=180) #x轴的刻度值上的数字旋转180度显示
plt.xlabel('X')
plt.ylabel('Y')
plt.grid()
plt.show()


### 6. 概率分布
### 6.1 均匀分布
x = np.random.rand(10000) # 返回一个或一组服从“0~1”均匀分布的随机样本值 [0,1)
t = np.arange(len(x))
# hist(x, 柱数) 直方图
plt.hist(x, bins=30, color='m', alpha=0.3, label=u'均匀分布') # 直方图,画30个柱,alpha透明度/颜色深浅
#plt.plot(t, x, 'g.', label=(u'均匀分布')) # 用点画图
plt.legend(loc='best')
plt.grid()
plt.show()


### 6.2 用均匀分布验证中心极限定理
Y = np.zeros(10000) # 生成(10000,)的元素全为0的列向量
for i in range(5000): # 重复5000次实验(重复的是均匀分布)
    # random.uniform()函数,均匀分布的随机采样
    Y += np.random.uniform(-5, 5, 10000) # 生成X~U(-5, 5)的均匀分布,并且此均匀分布Xn中n=10000;将生成的均匀分布中的x1,x2,````x10000依次放入空向量中,重复5000次实验
# 得到的Yi相当于∑Xi
Y /= 1000 # 除不除应该都可以吧,图像的形状都是一样的
plt.hist(Y, bins=100, color='g', alpha=0.5, density=1, label=u'均匀分布叠加5000次') # normed/density向量归一化,各元素平方和为1,方向不变;bins生成100个柱体
plt.legend(loc='upper left')
plt.grid()
plt.show()



### 6.2.1 用泊松分布验证中心极限定理
# 泊松分布的图像
lamda = 7
p = sp.stats.poisson(lamda) # scipy.stats.poisson() 生成泊松分布
# sp.stats.分布.rvs(loc=期望,scale=标准差,size=生成随机数的个数)产生服从指定分布的随机数
x = p.rvs(size=1000)
# x = sp.stats.poisson.rvs(7,np.sqrt(7), size=1000) # 同上
mx = 30
r = (0, mx) # tuple类型
bins=r[1] - r[0] # 30个柱体
plt.figure(figsize=(15, 8), facecolor='w')
# plt.subplot(a, b, n) a*b个坐标轴中的第n个
plt.subplot(121) # 新建一个figure,在一个figure里画多个坐标轴,1行2列中的第一个图像
plt.hist(x, bins=bins, range=r, color='g', alpha=0.7, density=1) # range筛选数据的范围,默认为从小到大所有
t = np.arange(0,mx+1)
# scipy.stats.poisson.pmf(x, loc=期望, scale=标准差) # 泊松分布在x处的概率密度函数的函数值f(x) pmf等同于之前的pdf
plt.plot(t, p.pmf(t), 'ro-', lw=2) # 描点描线,横坐标为t,纵坐标为f(t) lw=linewidth
plt.grid(1)


# 验证
plt.subplot(122)
a = np.zeros(10000, dtype=np.float) # 浮点型
p = stats.poisson(lamda)
for i in np.arange(1000):
    a +=p.rvs(size=10000)
a /= 1000
plt.hist(a, bins=30, color='g', alpha=0.7, density=1)
plt.grid(b=True, which='both') # 在图像中用所有的数据画图,默认为major用主要的数据画图,占比极少的那部分/不影响最终图形的那部分不参与绘图
plt.show()


# 生成泊松分布 方法二
# 使用random.poisson()生成泊松分布随机数
x = np.random.poisson(lam=7, size=1000)  # 产生服从泊松分布的随机数
print(x)
pillar = 30
a = plt.hist(x, bins=pillar, density=0, range=[0, pillar], color='g', alpha=0.5)
plt.grid()
plt.show()
print(a)  # a由两个数组组成,第0个数组表示纵坐标(乱序),第1个表示横坐标(从小到大排序);纵坐标是频次,总和为1000(归一化之后表示频率,因为总和为1)
print(a[0].sum()) # 和为1


### 6.4 直方图的使用
mu = 2
sigma = 3
# data~N(2, 9)
# np.random.randn() 从标准正态分布中随机采样
data = mu + sigma * np.random.randn(1000)  # 生成1000个服从标准正态分布的随机数
h = plt.hist(data, 30, density=1, color='#FFFFA0')  # 十六进制颜色码
x = h[1]
y = norm.pdf(x, loc=mu, scale=sigma)  # 正态分布函数值
plt.plot(x, y, 'r-', x, y, 'ro', linewidth=2, markersize=4)
plt.grid()
plt.show()



### 6.5 插值(不懂)
x = np.random.poisson(lam=7, size=1000)  # 产生服从泊松分布的随机数
pillar = 30
a = plt.hist(x, bins=pillar, density=0, range=[0, pillar], color='g', alpha=0.5)
plt.show()
rv = sp.stats.poisson(7)
x1 = a[1]
y1 = rv.pmf(x1) # 概率密度函数值
itp = BarycentricInterpolator(x1, y1) # 拉格朗日重心插值公式
x2 = np.linspace(x.min(), x.max(), 50)
y2 = itp(x2)
cs = CubicSpline(x1, y1) # 三次样条插值公式
plt.plot(x2, cs(x2), 'm--', lw=5, label='CubicSpline')
plt.plot(x2, y2, 'g-', lw=3,label='BarycentricInterpolator')
plt.plot(x1, y1, 'r-', lw=1, label='Actural Value') # 原始值
plt.legend(loc='upper right')
plt.grid()
plt.show()



### 6.6 泊松分布的两种表示方法
size = 1000
lamda = 5
p = np.random.poisson(lam=lamda, size=size)
plt.figure()
plt.hist(p, bins=range(3*lamda), histtype='bar', align='left', color='r', rwidth=0.8, density=1) # histtype柱的类型,默认为bar,还可设为step;rwidth柱的宽度;align对齐方式,默认为mid
plt.grid(b=True, ls=':') # ls=linestyle虚线的类型为····
plt.xticks(range(0, 19, 2)) # 设置x轴刻度
plt.title('Numpy.random.poisson', fontsize=13)

plt.figure()
r = stats.poisson(mu=lamda)
p = r.rvs(size=size)
plt.hist(p, bins=range(3*lamda), color='r', align='right', rwidth=0.3, density=1)
plt.grid(b=1, ls='--')
plt.title('scipy.stats.poisson', fontsize=13)
plt.show()



### 7 用matplotlib绘制三维图像
###7.1 np.mgrid()函数生成三维空间向量(利用广播机制)
# z = np.mgrid[a:x:m, b:y:n] 两个参数,生成一个三维空间向量由两个数组z[0]和z[1]组成,步长分别为m和n, [a, x) [b, y)
# 第二种:z = np.mgrid[a:x:cj, b:y:dj] 生成平均分为c/d个元素,左闭右闭,[a, x] [b, y]
# 例如第一种:
# 两个数组的行数由函数第一个参数决定(2 3 4),共三行;列数由第二个参数决定(1 2)共两列;默认步长为1,左闭右开;分成的元素由mn或cd决定
# 第一个数组z[0]的元素由第一个参数决定(2 3 4),共三种元素;第二个数组z[1]的元素由第二个参数决定(1 2),共两种元素
# 第一个数组z[0]的元素行相同;第二个数组z[1]的元素列相同
z = np.mgrid[2:5, 1:3] # 默认步长为1,左闭右开
x, y = z[0], z[1]
print('x=', x)
print('y=', y)
# 结果:
# x= [[2 2]
# #  [3 3]
# #  [4 4]]
# # y= [[1 2]
# #  [1 2]
# #  [1 2]]

z = np.mgrid[2:5, 3:4]
x, y = z[0], z[1]
print('x=', x)
print('y=', y)
# 结果:
# x= [[2]
#  [3]
#  [4]]
# y= [[3]
#  [3]
#  [3]]

z = np.mgrid[2:5:0.5, 1:3:1] # 步长分别为0.5和1,左闭右开
x, y = z[0], z[1]
print('x=', x)
print('y=', y)
# 结果:
# x= [[2.  2. ]
#  [2.5 2.5]
#  [3.  3. ]
#  [3.5 3.5]
#  [4.  4. ]
#  [4.5 4.5]]
# y= [[1. 2.]
#  [1. 2.]
#  [1. 2.]
#  [1. 2.]
#  [1. 2.]
#  [1. 2.]]

z = np.mgrid[2:5:6j, 1:3:2j] # 平均分为6个元素和2个元素,左右均闭
x, y = z[0], z[1]
print('x=', x)
print('y=', y)
# 结果:
# x= [[2.  2. ]
#  [2.6 2.6]
#  [3.2 3.2]
#  [3.8 3.8]
#  [4.4 4.4]
#  [5.  5. ]]
# y= [[1. 3.]
#  [1. 3.]
#  [1. 3.]
#  [1. 3.]
#  [1. 3.]
#  [1. 3.]]

z = np.mgrid[2:5:0.5, 1:3:2]
x, y = z[0], z[1]
print('x=', x)
print('y=', y)
# 结果:
# x= [[2. ]
#  [2.5]
#  [3. ]
#  [3.5]
#  [4. ]
#  [4.5]]
# y= [[1.]
#  [1.]
#  [1.]
#  [1.]
#  [1.]
#  [1.]]



### 7.2 np.meshgrid()函数 生成网格点坐标矩阵(空间网格坐标)或者说将数据网格化
# x, y = np.meshgrid(u, v) 生成空间网格线,返回两个矩阵,利用到笛卡尔乘积;uv为一维数组
# 返回的两个矩阵xy,行数由u控制,列数由v控制
# x列元素相同,y行元素相同
u = np.linspace(-3, 2, 5)
v = np.linspace(4, 8, 7)
x, y = np.meshgrid(u, v)
print('x=', x)
print('y=', y)
# 结果:
# x= [[-3.   -1.75 -0.5   0.75  2.  ]
#  [-3.   -1.75 -0.5   0.75  2.  ]
#  [-3.   -1.75 -0.5   0.75  2.  ]
#  [-3.   -1.75 -0.5   0.75  2.  ]
#  [-3.   -1.75 -0.5   0.75  2.  ]
#  [-3.   -1.75 -0.5   0.75  2.  ]
#  [-3.   -1.75 -0.5   0.75  2.  ]]
# y= [[4.         4.         4.         4.         4.        ]
#  [4.66666667 4.66666667 4.66666667 4.66666667 4.66666667]
#  [5.33333333 5.33333333 5.33333333 5.33333333 5.33333333]
#  [6.         6.         6.         6.         6.        ]
#  [6.66666667 6.66666667 6.66666667 6.66666667 6.66666667]
#  [7.33333333 7.33333333 7.33333333 7.33333333 7.33333333]
#  [8.         8.         8.         8.         8.        ]]




### 7.3 add_subplot()与plt.subplot()的区别
from mpl_toolkits.mplot3d import Axes3D
# 为了绘制 3D 图形,需要调用 Axes3D 对象的 add_subplot(),plot_surface() 等方法来完成
# pyplot的方式中plt.subplot()和面向对象中的对象.add_subplot()的参数和含义都相同。
# 一个窗口显示多个坐标轴
a = plt.figure()
ax = a.add_subplot(335, projection='3d') # 这里的3d投射要调用一个Axes3D工具包
axx = plt.subplot(335, projection='3d')
plt.show() #显示三维坐标轴



### 7.4 plot.surface()函数 画三维图像
from matplotlib import cm
# ax.plot_surface(x, y, z, rstride=5, cstride=5, cmap=cm.coolwarm, linewidth=0.1) # 不懂linewidth在哪体现出来
ax.plot_surface(x, y, z, rstride=5, cstride=5, cmap=plt.get_cmap('coolwarm'), linewidth=0.1)
# ax.plot_surface(x, y, z, rstride=3, cstride=3, cmap=cm.gist_heat, linewidth=0.5)
# rstride:row stride 行跨度 类似于像素点的大小 每一个网格在平面上投影的大小是5*5
# cstride:column stride 列跨度
# cmap 设置图形颜色
# cmaps = [('Perceptually Uniform Sequential',
#           ['viridis', 'inferno', 'plasma', 'magma']),
#          ('Sequential', ['Blues', 'BuGn', 'BuPu',
#                          'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd',
#                          'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu',
#                          'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd']),
#          ('Sequential (2)', ['afmhot', 'autumn', 'bone', 'cool',
#                              'copper', 'gist_heat', 'gray', 'hot',
#                              'pink', 'spring', 'summer', 'winter']),
#          ('Diverging', ['BrBG', 'bwr', 'coolwarm', 'PiYG', 'PRGn', 'PuOr',
#                         'RdBu', 'RdGy', 'RdYlBu', 'RdYlGn', 'Spectral',
#                         'seismic']),
#          ('Qualitative', ['Accent', 'Dark2', 'Paired', 'Pastel1',
#                           'Pastel2', 'Set1', 'Set2', 'Set3']),
#          ('Miscellaneous', ['gist_earth', 'terrain', 'ocean', 'gist_stern',
#                             'brg', 'CMRmap', 'cubehelix',
#                             'gnuplot', 'gnuplot2', 'gist_ncar',
#                             'nipy_spectral', 'jet', 'rainbow',
#                             'gist_rainbow', 'hsv', 'flag', 'prism'])]



### 7.5 完整代码
u = np.linspace(-3, 3, 101)
x, y = np.meshgrid(u, u)
z = x*y*np.exp(-(x**2 + y**2)/2) / math.sqrt(2*math.pi)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
#ax.plot_surface(x, y, z, rstride=5, cstride=5, cmap=cm.coolwarm, linewidth=0.1)  #
ax.plot_surface(x, y, z, rstride=5, cstride=5, cmap=plt.get_cmap('coolwarm'), linewidth=0.1)
# ax.plot_surface(x, y, z, rstride=3, cstride=3, cmap=cm.gist_heat, linewidth=0.5)
plt.show()



### 8 scipy
### 8.1 线性回归
### 8.1.1 线性回归例1(结果较好)
from scipy.optimize import leastsq
# leastsq 求出想要拟合的函数的参数(求出“满足”已知的所有的坐标点的一个函数):最小二乘法
# leastsq(func, x0, args=())
# func 是我们自己定义的一个计算误差的函数
# x0 是计算的初始参数值
# args 是指定func的其他参数(x, y)

# 定义一个计算误差的函数
def residual(t, x, y): # 参数t
    return y - (t[0] * x ** 2 + t[1] * x + t[2])
    
x = np.linspace(-2, 2, 50)
A, B, C = 2, 3, -1
y = (A * x ** 2 + B * x + C) + np.random.rand(len(x))*0.75 # 在二次函数周围生成一些点来模拟一条很乱的曲线
# leastsq 非线性最小二乘法
t = leastsq(residual, [0, 0, 0], args=(x, y))
print('t=',t) # 得到的t由两部分组成
theta = t[0] # 得到三个拟合后的值
print('真实值:', A, B, C)
print('预测值:', theta)
y_hat = theta[0] * x ** 2 + theta[1] * x + theta[2] # 根据拟合出来的参数,构建函数
plt.plot(x, y, 'r-', linewidth=2, label=u'Actual')
plt.plot(x, y_hat, 'g-', linewidth=2, label=u'Predict')
plt.legend(loc='upper left')
plt.grid()
plt.show()
# 结果:
# t= (array([ 2.04320419,  2.99315221, -0.71851711]), 2)
# 真实值: 2 3 -1
# 预测值: [ 2.04320419  2.99315221 -0.71851711]


### 8.1.2 线性回归例2(结果较差)
def residual2(t, x, y):
    print(t[0], t[1])
    return y - (t[0]*np.sin(t[1]*x) + t[2])

x = np.linspace(0, 5, 100)
a = 5
w = 1.5
phi = -2
y = a * np.sin(w*x) + phi + np.random.rand(len(x))*0.5

t = leastsq(residual2, [3, 5, 1], (x, y))
theta = t[0]
print('真实值:', a, w, phi)
print('预测值:', theta)
y_hat = theta[0] * np.sin(theta[1] * x) + theta[2]
plt.plot(x, y, 'r-', linewidth=2, label='Actual')
plt.plot(x, y_hat, 'g-', linewidth=2, label='Predict')
plt.legend(loc='lower left')
plt.grid()
plt.show()
# 结果:
# 3 5
# 3.0 5.0
# 3.0 5.0
# 3.0000000447034836 5.0
# 3.0 5.000000074505806
# 3.0 5.0
# -0.35025586482811155 5.0103467863606275
# -0.35025585960889244 5.0103467863606275
# -0.35025586482811155 5.010346861020612
# -0.35025586482811155 5.0103467863606275
# -0.3464040959008468 4.891609082124287
# `
# `
# `
# `
# `
# -0.356176342748945 4.970623346809979
# -0.356176342748945 4.97062327274192
# -0.35618993585593384 4.970833985070044
# 真实值: 5 1.5 -2
# 预测值: [-0.35617634  4.97062327 -1.27914153]




### 8.2 用scipy计算函数极值(fmin不懂!!!!!!!)
import scipy.optimize as opt

# x ** x        x > 0
# (-x) ** (-x)  x < 0
def f(x):
    y = np.ones_like(x)
    i = x > 0
    y[i] = np.power(x[i], x[i])
    i = x < 0
    y[i] = np.power(-x[i], -x[i])
    return y
    
a = opt.fmin(f, 1)
b = opt.fmin_cg(f, 1)
c = opt.fmin_bfgs(f, 1)
print('a=', a, '1/a=', 1/a, 'e=', math.e)
print('b=', b, '1/b=', 1/b, 'e=', math.e)
print('c=', c, '1/c=', 1/c, 'e=', math.e)
# 结果:
# Optimization terminated successfully.
#          Current function value: 0.692201
#          Iterations: 16
#          Function evaluations: 32
# Optimization terminated successfully.
#          Current function value: 0.692201
#          Iterations: 4
#          Function evaluations: 30
#          Gradient evaluations: 10
# Optimization terminated successfully.
#          Current function value: 0.692201
#          Iterations: 5
#          Function evaluations: 24
#          Gradient evaluations: 8
# a= [0.36787109] 1/a= [2.71834351] e= 2.718281828459045
# b= [0.36787948] 1/b= [2.71828157] e= 2.718281828459045
# c= [0.36787942] 1/c= [2.71828199] e= 2.718281828459045




# marker	description
# ”.”	point
# ”,”	pixel
# “o”	circle
# “v”	triangle_down
# “^”	triangle_up
# “<”	triangle_left
# “>”	triangle_right
# “1”	tri_down
# “2”	tri_up
# “3”	tri_left
# “4”	tri_right
# “8”	octagon
# “s”	square
# “p”	pentagon
# “*”	star
# “h”	hexagon1
# “H”	hexagon2
# “+”	plus
# “x”	x
# “D”	diamond
# “d”	thin_diamond
# “|”	vline
# “_”	hline
# TICKLEFT	tickleft
# TICKRIGHT	tickright
# TICKUP	tickup
# TICKDOWN	tickdown
# CARETLEFT	caretleft
# CARETRIGHT	caretright
# CARETUP	caretup
# CARETDOWN	caretdown

Matplotlib中Legend图例语法与使用

np.meshgrid()函数的理解

最小二乘法

机器学习中最小二乘法可以理解为就是通过最小化误差的平方和来寻找最佳的匹配函数。一般常用于曲线的拟合。
关于曲线的拟合,就是求出最佳的k,b的值来找出好的曲线实现好的分类效果。
一般情况下拟合的曲线为k*x+b一次函数,不过如果需要拟合的函数不是一次函数,就比较麻烦了。python的科学计算包scipy的里面提供了一个函数,可以求出任意的想要拟合的函数的参数。那就是scipy.optimize包里面的leastsq函数。

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务