关于模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
导入:
import module1
引用模块内的函数:
模块名.函数名
# 导入模块
import support
# 现在可以调用模块里包含的函数了
support.print_func("Runoob")
1. 导入模块
可以通过输入import关键字来导入模块
import numpy
将模块通过as关键字来命名一个简称
import numpy as np
有时不必导入整个模块,就像
from scipy.stats import norm
练习:计算运行一个函数所需要的时间
import timeit
def funl (x, y):
return x**2 + y**3
t_start = timeit.default_timer() # 开始时间
z = funl(109.2, 367.1) # 执行函数
t_end = timeit.default_timer() # 结束时间
cost = t_end -t_start
print ( 'Time cost of funl is %f' %cost)
2. 有用的模块
-
NumPy:多维数组的有效操作。 高效的数学函数。
-
Matplotlib:可视化:2D和(最近)3D图
-
SciPy:大型库实现各种数值算法,例如:
线性和非线性方程的解 优化 数值整合
-
Sympy:符号计算(解析的 Analytical)
-
Pandas:统计与数据分析
Numpy (模块一)
3. Numpy
ndarray类型(新的数据类型)
NumPy提供了一种新的数据类型:ndarray(n维数组)。
与元组和列表不同,数组只能存储相同类型的对象(例如只有floats或只有ints)
这使得数组上的操作比列表快得多; 此外,阵列占用的内存少于列表。
数组为列表索引机制提供强大的扩展。
创建ndarray
In [1] : np.array([2, 3, 6, 7]) #注意小括号和中括号
Out[l] : array([2, 3, 6, 7])
In [2] : np.array([2, 3, 6, 7.])
Out [2] : array([ 2., 3., 6., 7.]) <- Hamogenaous
In [3] : np.array( [2, 3, 6, 7+ij])
Out [3] : array([ 2.+O.j, 3.+O.j, 6.+O.j, 7.+1.j])
只能是相同类型的数据,如果不一样会统一
创建均匀间隔的数组
- arange
range(start, stop, step)的所有三个参数即起始值,结束值,步长都是可以用的 另外还有一个数据的dtype参数
in[2]:np.arange(10,100,20,dtype = float)
Out [2]:array([10.,30.,50.,70.,90.])
- linspace
linspace(start,stop,num)返回数字间隔均匀的样本,按区间[start,stop]计算
in[3]:np.linspace(0.,2.5,5) #从0开始,到2.5结束,然后分成5等份
Out [3]:array([0.,0.625,1.25,1.875,2.5])
4. 多维数组矩阵
刚刚创建的是一维数组,现在创建多维数组
In [1] : a = np.array([[1, 2, 3] [4, 5, 6]]) #这个矩阵为二行三列
^ 第一行 (Row 1)
In [2] : a
Out [2] : array([[l, 2, 3] , [4, 5, 6]])
In [3] : a.shape #<- 行、列数等 (Number of rows, columns etc.)
Out [3] : (2,3)
In [4] : a.ndim #<- 维度数 (Number of dimensions)
Out [4] : 2
In [5] : a.size #<- 元素数量 (Total number of elements)
Out [5] : 6
5. 改变组的形状
.reshape
a = np .arange(0, 20, 1) #生成一个一维数列,从1到19,步长为1
b = a.reshape((4, 5)) #对a重塑形状为4行5列
c = a.reshape((20, 1)) #重塑形状为20行1列
d = a.reshape((-1, 4)) #-1:自动确定
#a.shape =(4, 5) #改变a的形状
6. Size(N,),(N,1)和(1,N)
- Size(N, )表示数组是一维的。
- Size(N,1)表示数组是维数为2, N列和1行。
- Size(1,N)表示数组是维数为2, 1行和N列。
Examples
a = np.array([1,2,3,4,5])
b = a.copy () # 复制一下
c1 = np.dot(np.transpose(a), b) # .dot 为矩阵乘积,一维乘一维为向量内积
print(c1)
c2 = np.dot(a, np.transpose(b))
print(c2)
ax = np.reshape(a, (5,1)) # 5行一列
bx = np.reshape(b, (1,5)) # 一列五行
c = np.dot(ax, bx) # 两个矩阵的乘积
print(c)
使用完全相同的元素填充数组
In [1] : np.zeros(3) # zero(),全0填充数组
Out[l] : array([ O., 0., 0.])
In [2] : np.zeros((2, 2), complex)
Out[2] : array([[ 0.+0.j, 0.+0.j],
[ 0.+O.j, 0.+0.j]])
In [3] : np.ones((2, 3)) # ones(),全1填充数组
Out[3] : array([[ 1., 1., 1.],
[ 1., 1., 1.]])
7. 使用随机数字填充数组
.random.rand
- rand: 0和1之间均匀分布的随机数
- randn: 均值为0,标准差为1的标准(高斯)正态分布
In [1] : np.random.rand(2, 4) # 二行四列
Out[1] : array([[ 0.373767 , 0.24377115, 0.1050342 , 0.16582644] ,
[ 0.31149806, 0.02596055, 0.42367316, 0.679752491])
In [2]: np.random.randn(2, 4)
Out[2]: array([[ 0.87747152, 0.39977447, -0.83964985, -1.05129899],
[-1.07933484, 0.49448873, -1.32648606, -0.94193424]])
8. 数组切片 (一维)
提取部分,主要使用冒号: 几到几
- 以格式start:stop可以用来提取数组的片段(从开始到不包括stop)
In [77]:a = np.array([0,1,2,3,4])
Out[77]:array([0,1,2,3,4])
In [78]:a [1:3] #<--index从0开始 ,所以1是第二个数字,即对应1到3结束,就是到第三个数字,对应是2
Out[78]:array([1,2])
- start可以省略,在这种情况下,它被设置为零(Notes:貌似留空更合适)
- stop也可以省略,在这种情况下它被设置为数组长度:
- 也可以使用负指数,具有标准含义:
In [81]:a [1:-1]
Out[81]:array([1,2,3]) # <-- stop为-1表示倒数第二个数
- 整个数组:a或a [:]
- 要获取,例如每个其他元素,您可以在第二个冒号后面指定第三个数字(步骤(step)):
In [79]: a [::2]
Out[79]: array([0,2,4])
In [80]: a [1:4:2]
Out[80]: array([1,3])
数组索引 (二维)
主要通过第几行第几列来实现
In [93] : a = np.arange(12) ; a.shape = (3, 4); a
Out[93] : array([[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11]])
In [94] : a[1,2] # 索引第二行,第三列的数值
Out[94] : 6
In [95] : a[1,-1] # 索引第二行,倒数第一列的数值
Out[95] : 7
数组切片(二维)
与列表差不多。表示第n行所有值则是 a[n,:]
In [96] : a = np.arange(12); a.shape = (3, 4); a
Out[96] : array([[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9,10,11]])
In [97] : a[:,1] # 所有行,第二列
Out[97] : array([1,5,9])
In [98] : a[2,:] # 第三行,所有列
Out[98] : array([ 8, 9, 10, 11])
In [99] : a[1][2]
Out[99] : 6
Examples
>>> a[0,3:5]
array( [3,4] )
>>> a[4:,4:]
array([[44, 45],
[54, 55]])
>>> a[:,2]
array([2,12,22,32,42,52])
>>> a[2: :2, ::2]
array([[20, 22, 24]
[40, 42, 44]])
9. 副本和视图
上面创建的切片都是视图,会和原数组相链接
采用一个NumPy数组的切片可以在原始数组中创建一个视图。 两个数组都指向相同的内存。因此,当修改视图时,原始数组也被修改:
In [30] : a = np.arange(5); a
Out[30] : array([0, 1, 2, 3, 4])
In [31] : b = a[2:]; b
Out[31] : array([2, 3, 4])
In [32] : b[0] = 100
In [33] : b
Out[33] : array([100, 3, 4])
In [34] : a
Out[34] : array([0,1,100,3,4])
制作副本:
在切片最后加上 .copy
为避免修改原始数组,可以制作一个切片的副本
In [30] : a = np.arange(5); a
Out[30] : array([0, 1, 2, 3, 4])
In [31] : b = a[2:].copy(); b
Out[31] : array([2, 3, 4])
In [32] : b[0] = 100
In [33] : b
Out[33] : array([1OO, 3, 4])
In [34] : a
Out[34] : array([ 0, 1. 2, 3, 4])
10. 矩阵乘法
dot用于矩阵乘法运算
- 运算符 * 表示元素乘法,而不是矩阵乘法
In [1]: A = np.array([[1, 2],[3, 4]])
In [2]: A
Out[2]: array([[1, 2],
[3, 4]])
In [3]: A * A
Out[3]: array([[1, 4],
[9, 16]]) #把矩阵中的每个元素平方,而不是两矩阵相乘
使用dot()函数进行矩阵乘法
In [4]: np.dot(A, A)
Out[4]: array([[ 7, 10],
[15, 22]]) #矩阵第一行为[ 7, 10]
- dot()方法也适用于矩阵向量(matrix-vector)乘法:
In [1]: A
Out[1]: array([[1, 2],[3, 4]])
In [2]: x = np.array([10, 20])
In [3]: np.dot(A, x)
Out[3]: array([ 50, 110])
In [4]: np.dot(x, A)
Out[4]: array([ 70, 100])
11. 数组的保存以及读取
输出:savetxt()将表保存到文本文件。
读取:
输出
In [1]: a = np,linspace(0. 1, 12); a,shape ' (3, 4); a
Out [1] :
array([[ O. , 0.09090909, 0.18181818, 0.27272727],
[ 0.36363636, 0.45454545, 0.54545455, 0.63636364],
[ 0.72727273, 0.81818182. 0.90909091, 1.]])
In [2] : np.savetxt("myfile.txt", a)
- save()将表保存为Numpy“.npy”格式的二进制文件
In [3] : np.save("myfile" ,a)
生成一个二进制文件myfile .npy,其中包含一个可以使用np.load()加载的文件。
读取
- loadtxt()将以文本文件存储的表读入数组。
- 默认情况下,loadtxt()假定列是用空格分隔的。 您可以通过修改可选的参数进行更改。 以散列(#)开头的行将被忽略。
Numpy包含更高效率的功能
np.log
np.maximum
np.sin
np.exp
np.abs
Scipy (库)
13. SciPy的结构
scipy.integrate 积分和普通微分方程
scipy.linalg 线性代数
scipy.ndimage 图像处理
scipy.optimize 优化和根查找(root finding)
scipy.special 特殊功能
scipy.stats 统计功能
加载库里的一个模块
from scipy import linalg
14. scipy.linalg 线性代数
求线性方程的解
linalg.solve求解线性方程 linalg.eig求特征值和特征向量 linalg.det求行列式
import numpy as np
from scipy import linalg
A = np.random.randn(5, 5)
b = np.random.randn(5)
x = linalg.solve(A, b) # 解 Ax = b
eigen = linalg.eig(A) # 求特征值和特征向量
det = linalg.det(A) # 求A的行列式
print(det)
eig()(特征值和特征向量),det()(行列式)
15. 积分
integration.quad是一维积分的自适应数值积分的函数。
16. 用Scipy进行统计
Matplotlib (制图)
17. 最简单的制图
导入库需要添加以下内容
from matplotlib import pyplot as plt
代码
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 201) # 均匀区间取值
plt.figure(figsize = (3, 3)) # new fig
plt.plot(x, x**0.3, 'r--') # 红虚线
plt.plot(x, x-1, 'k-') # 斜线
plt.plot(x, np.zeros_like(x), 'k-') # 水平实线
plt.show() #绘图要在最后加上这一句才会显示
Note:
x轴在plt.plot函数中应与y轴的尺寸相同。
18. 多个制图图例标签和标题
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 201) # 等区间取点
plt.figure(figsize = (4, 4))
for n in range(2, 5):
y = x ** (1 / n)
plt.plot(x, y, label=’x^(1/’ \
+ str(n) + ’)’)
plt.legend(loc = ’best’) # 设置图例的位置
plt.xlabel(’X axis‘) # X轴的标签名
plt.ylabel(’Y axis‘) # Y轴的标签名
plt.xlim(-2, 10) # Y的刻度范围
plt.title(’Multi-plot e.g. ’, fontsize = 18) # 标题
19. 绘制子图 (Subplots)
多幅图
import numpy as np
import matplotlib.pyplot as plt
def pffcall(S, K):
return np.maximum(S - K, 0.0)
def pffput(S, K):
return np.maximum(K - S, 0.0)
# 图一
S = np.linspace(50, 151, 100)
fig = plt.figure(figsize=(12, 6)) # 整图的尺寸
sub1 = fig.add_subplot(121) # 列,行,数字 一行两列,放在第一个
sub1.set_title('Call', fontsize = 18) # 标题
plt.plot(S, pffcall(S, 100), 'r-', lw = 4) # 红线
plt.plot(S, np.zeros_like(S), 'black',lw = 1) # 黑横线
sub1.grid(True) # 是否添加网格
sub1.set_xlim([60, 120]) # 轴刻度
sub1.set_ylim([-10, 40])
# 图二
sub2 = fig.add_subplot(122) # 一行二列 第二张图
sub2.set_title('Put', fontsize = 18)
plt.plot(S, pffput(S, 100), 'r-', lw = 4)
plt.plot(S, np.zeros_like(S), 'black',lw = 1)
sub2.grid(True)
sub2.set_xlim([60, 120])
sub2.set_ylim([-10, 40])
plt.show()
Figure: 一个子图的例子 (注释:这里,可以把Figure,即fig理解为一张大画布,你把它分成了两个子区域(sub1和sub2),然后在每个子区域各画了一幅图。)
20. 在绘制的图上添加文本和注释
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
def call(S, K=100, T=0.5, vol=0.6, r=0.05): # 定义call函数
d1 = (np.log(S/K) + (r + 0.5 * vol**2) \
*T) / np.sqrt(T) / vol
d2 = (np.log(S/K) + (r - 0.5 * vol**2) \
*T) / np.sqrt(T) / vol
return S * norm.cdf(d1) - K * \
np.exp(-r * T) * norm.cdf(d2)
def delta(S, K=100, T=0.5, vol=0.6, r=0.05): # 定义函数Δ
d1 = (np.log(S/K) + (r + 0.5 * vol**2)\
*T) / np.sqrt(T) / vol
return norm.cdf(d1)
S = np.linspace(40, 161, 100)
fig = plt.figure(figsize=(7, 6)) # 定义画布大小
ax = fig.add_subplot(111)
plt.plot(S,(call(S)-call(100)),’r’,lw=1)
plt.plot(100, 0, ’ro’, lw=1)
plt.plot(S,np.zeros_like(S), ’black’, lw = 1)
plt.plot(S,call(S)-delta(100)*S- \
(call(100)-delta(100)*100), ’y’, lw = 1)
ax.annotate(’$\Delta$ hedge’, xy=(100, 0), \ #注释 :$\Delta$为Δ,xytext为文本位置
xytext=(110, -10),arrowprops= \
dict(headwidth =3,width = 0.5, \
facecolor=’black’, shrink=0.05))
ax.annotate(’Original call’, xy= \
(120,call(120)-call(100)),xytext\
=(130,call(120)-call(100)),\
arrowprops=dict(headwidth =10,\
width = 3, facecolor=’cyan’, \
shrink=0.05))
plt.grid(True) # 网格
plt.xlim(40, 160) # x轴刻度
plt.xlabel(’Stock price’, fontsize = 18)
plt.ylabel(’Profits’, fontsize = 18)
plt.show()
3D plot of a function with 2 variables
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
x, y = np.mgrid[-5:5:100j, -5:5:100j]
z = x**2 + y**2
fig = plt.figure(figsize=(8, 6))
ax = plt.axes(projection='3d')
surf = ax.plot_surface(x, y, z, rstride=1,\
cmap=cm.coolwarm, cstride=1, \
linewidth=0)
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.title('3D plot of $z = x^2 + y^2$')
plt.show()