
【Python 版本:3.9.0】
** python的扩展库NumPy、pandas等库和MATLAB才是真正的数学统计专家!本文旨在仅以python内置库,实现以下目标:
1)写出真正具有实用性的小程序
2)掌握简单程序的编程思路,练习flow control
3)了解一些关于内置math库的东西
4)复习数学/统计基础知识
目录
1. 求阶乘、累乘
2. 求排列数、组合数
3. 求gamma函数值
4. 求三角函数、对数
5. 定义法求导数
6. 定义法求偏导数
7. 求积分
8. 求点乘、叉乘
9. 求泊松分布pmf cdf
10. 求二项分布pmf cdf
11. 求正态分布cdf
基础知识:
1. math是python内置库。只需要import math后即可调用。
2. e,pi在内置math库里。使用math.e math.pi可以调用
3. 1e-5 表示10^-5。数据类型是浮点数!如1e4 = 10000.0
1. 求阶乘、累乘 math.factorial() math.prod()
这个可以自己用for循环、递归写,但是内置math库里早已准备好了:
import math print(math.factorial(5)) # output 120 import math a = list(range(1,5)) # a=[1,2,3,4] print(math.prod(a)) # output 24
2. 求排列数、组合数 math.perm() math.comb()
math库里也早早准备好了排列、组合数的函数!nPr,nCr,函数参数先是n再是r。
import math print(math.perm(7,3)) # 7P3 # output 210 import math print(math.comb(7,3)) # 7C3 # output 35
3. gamma 函数 math.gamma()
gamma函数是数学、统计上的一个重要函数。内置math库里已经提供好了相关函数:

import math print(math.gamma(1)) print(math.gamma(0.5)) # output 1.0 1.7724538509055159
4. 三角函数 对数
三角函数、对数在math库里都有。
常规三件套:math.sin() math.cos() math.tan()
双曲三件套:math.sinh() math.cosh() math.tanh()
反三角三件套:math.asin() math.acos() math.atan()
ps:输入值都是弧度!没有sec正割等函数。
math.radians() math.degrees()可以实现角度、弧度互换。
对数函数math.log(x,base=math.e) 默认base是e,可以自己改。
import math print(math.log(10)) # base = e print(math.log(10,10)) # base = 10 print(math.sin(1)) # 1 is in radians # output 2.302585092994046 1.0 0.8414709848078965
5. 定义法求导数
使用原始极限定义求。f是需要求导的函数。h取一个比较小的数,1e-8,1e-12之类都行。

这样数值计算求出来的答案和正确答案可能有亿点点误差,自己考虑一下就行。
def f(x): return x**3-2*x+3 h = 1e-8 print((f(h)-f(0))/h) # output -1.999999987845058 (实际上就是-2)
6. 定义法求偏导数
使用原始极限定义求。f为要求导的多元函数,h取一个比较小的数,1e-8,1e-12都行。

这样数值计算求出来的答案和正确答案可能有亿点点误差,自己考虑一下就行。
import math h = 1e-8 def f(x, y): return x * ((x**2+y**2)**(-1.5)) * (math.e**math.sin(x*x*y)) print((f(1+h, 0)-f(1, 0)) / h) # output -1.999999943436137 (实际上就是-2)
7. 求积分
数值计算 定义法求积分。partition数取1e6 1e8之类都行。

和上面一样同样会有少量误差。
import math a = 1 # lower bound b = 2 # upper bound n = 100000 # partition number def f(x): return x * (math.sin(x)-1) sum_ = 0 for i in range(n): sum_ += ((b-a)/n) * f(a+((b-a)/n)*(i+0.5)) print(sum_) # output -0.059577579014353205
8. 求点乘 叉乘
点乘
第一种:直接公式法,仅限三维以内向量。
第二种:用for循环累加各项xi yi,可以拓展到高维向量。
第三种:第二种的列表生成式写法。
叉乘
第一种:公式法。
def dot_1(x1,x2,x3,y1,y2,y3): return x1*y1 + x2*y2 + x3*y3 def dot_2(vec1,vec2): sum = 0 for i in range(len(vec1)): sum = sum + vec1[i]*vec2[i] return sum def dot_3(vec1,vec2): new_list = zip(vec1,vec2) total = sum([i*j for i,j in new_list]) return total def cross(x1,x2,x3,y1,y2,y3): return (x2*y3-x3*y2, x3*y1-x1*y3, x1*y2-x2*y1) print(dot_1(1,2,3,5,6,7)) print(dot_2([1,2,3],[5,6,7])) print(dot_3([1,2,3],[5,6,7])) print(cross(1,2,3,5,6,7)) # output 38 38 38 (-4, 8, -4)
《NumPy乱杀系列》
感兴趣的同学可以自己上网搜索NumPy安装,以及简单使用(作者后面可能会出简单上手教程的)
import numpy a = numpy.array([1,2,3]) b = numpy.array([5,6,7]) print(numpy.dot(a,b)) print(numpy.cross(a,b)) #output 38 [-4 8 -4]
9. 求泊松分布pmf、cdf
先得到pmf,累加得到cdf。这里做了一点输入检测。
def possion_pmf(lam,x): if (isinstance(lam,str)) or (not isinstance(x,int)): raise TypeError if x < 0: raise ValueError return (lam**x)*(math.e**-lam)/math.factorial(x) def possion_cdf(lam,start,end): if (isinstance(lam,str)) or (not isinstance(start,int)) or (not isinstance(end,int)): raise TypeError if start > end: raise ValueError sum = 0 for x in range(start,end+1): sum += (lam**x)*(math.e**-lam)/math.factorial(x) return sum
10. 求二项分布pmf、cdf
先搞出二项分布pmf,使用阶乘。再累加得到cdf。这里做了一点输入检测。
def binomial_pmf(n,p,x): if (not isinstance(n,int)) or (isinstance(p,str)) or (not isinstance(x,int)): raise TypeError if x < 0: raise ValueError return math.comb(n,x)*(1-p)**(n-x)*p**x def binomial_cdf(n,p,start,end): if (isinstance(n,str)) or (isinstance(p,str)) or (not isinstance(start,int)) or (not isinstance(end,int)): raise TypeError if start > end: raise ValueError sum = 0 for x in range(start,end+1): sum += math.comb(n,x)*(1-p)**(n-x)*p**x return sum
11. 求正态分布cdf
实际上就是求积分。

import math a = 0 # lower bound b = 1 # upper bound n = 100000 # partition number mu = 0 sigma = 1 def f(x): return (1/(sigma*math.sqrt(2*math.pi)))*math.exp(-((x-mu)**2)/(2*sigma**2)) sum = 0 for i in range(n): sum += ((b-a)/n) * f(a+((b-a)/n)*(i+0.5)) print(sum)
其实9-11已经教了各位如何求单变量连续/离散型的分布的pmf, cdf 基本上改一下函数就可以扩展到其他分布类型。
多变量呢?别骂了别骂了,笔者STA2001在修,以后有机会补上!
把上述写在一个.py文件里。这样以后在同级目录其他py文件直接import 就可以快速调用这些函数了!
上述内容的源代码文件在下方百度网盘中!
【链接:https://pan.baidu.com/s/15ZRgr9yVck8GFhP01l-rwg
提取码:lxe1 】
上述内容结合互联网与自身实践而得。如有纰漏,或有疑问,敬请电邮至笔者邮箱:3038242641@qq.com