Python科学计算

268 阅读5分钟

1. Python简明教程

  • 长语句可用 续行符号 " \ " 来分成多行,如果一个语句包含一对括号(),那么我们可以在它们之间的任何位置点分行,而不需要使用续行符号 " \ "
a, b, c, d = 4, 5.5, 1.5+2j, 'a'
e = 6.0 * a - b * b + \  # 用"\"续行
        c ** (a + b + c)
f = 6.0 * a - b * b + c ** (  # 有()直接换行
        a + b + c)
  • 复数定义: 一个Python复数可以显式地定义为诸如c=1.5-0.4j,Python用 j 表示虚数单位
  • 构造单元素元组: 表达式 (foo) 的求值结果是去掉括号仅保留元素,正确的元组构造语法是 (foo, )
  • 列表解析: 列表解析不仅简洁,而且更快速,特别针对长列表,因为无须显式构造for循环结构
L1 = [2, 3, 5, 7, 11, 14]
L2 = []  # Empty list

L2 = [x**2 for x in L1]  # 用L1列表中元素的平方构造L2
L2 = [x*x for x in L1 if x%2]  # 用L1列表中奇数元素的平方构造L2
L2 = [x*y for x in L1 if x%2 for y in L1 if not y%2]  # 用L1列表中奇数与偶数的乘积构造L2
  • 规范的函数初始定义(内容延迟条件下):
# TBD: finish this function
def function():
    """描述函数的具体功能"""  # 用文档字符串描述函数
    pass
  • 函数的不同参数类型
def foo1(a, b, c): pass  # 位置参数
def foo2(a, b=7, c='i'): pass  # 关键字参数
def foo3(*args): pass  # 可变数量的位置参数
def foo4(a, b, *args, **kwargs): pass  # 可变数量的关键字参数
  • 格式化输出:
a, b, c, d = 5, 123.45678, 1234567.89, 'abc'

print("%5d, %010.3f, %13.4e, %-6s|" % (a, b, c, d) )
# %5d:输出五个字符,数值右对齐,用空格填充空白
# %010.3f:输出10个字符宽度的字符串,数值右对齐,用0填充空白
# %13.4e:保留小数点后四位数字,输出数值为13个字符宽度的字段,使用科学计数法(e表示)
# %-6s:输出6个字符宽度的字段,字符左对齐,用空格填充空白

  • 循环技巧 enumera()函数 会在每一次循环过程中提供两个参数,第一个代表列表元素的索引值,第二个代表列表中元素的内容
fruit = ["apple", "pear", "pineapple", "orange", "banana"]
for i, x in enumerate(fruit):
    print(i, x)

  • 字典的合并操作
a = {"ross": "123456", "xiaoming": "abc123"}
b = {"lilei": "111111", "zhangsan": "12345678"}

c = {**a, **b}  # 解包,将字典a和b中的内容直接填到这里
print(c)

  • 三元运算符
score = 99
s = "pass" if score > 60 else "fail"  # 三元运算符 if后面条件满足时表达式输出前面的值,否则输出else后的值

2. NumPy

创建数组

import numpy as np

m1 = np.array([1, 2, 3, 4, 5])  # 用array创建数组
m2 = np.zeros((3, 2))  # 用zeros创建3行2列的零矩阵
m3 = np.ones((2, 2))  # 用ones创建2行2列的1矩阵
m4 = np.arange(3, 7)  # 用arange创建递增或递减数组
m5 = np.linspace(0, 1, 5)  # 用linspace创建介于两个数之间,等间距分布的数
m6 = np.random.rand(2, 4)  # 用random.rand创建一个随机数组

  • 在NumPy中,数组默认的数据类型是64位的浮点数,不过我们可以在创建数组时,通过 dtype 指定其他的数据类型
m = np.zeros((3, 2), dtype=np.int32)
# 整型       np.int8/16/32/64
# 无符号整型 np.uint8/16/32/64
# 浮点数     np.float32/64
# 布尔值     bool
# 字符串     str
  • 对于现有的数组,我们也可以通过 astype(...) 来转换数据类型

基本运算

import numpy as np

a1 = np.array([1, 2, 3])
a2 = np.array([4, 5, 6])
b1 = np.arange(9).reshape(3, 3)
b2 = np.ones((3, 3))

print(f"a1+b1: {a1+b1}")  # 将两个数组扩展成相同维数,再进行运算
print(f"a1·a2: {np.dot(a1, a2)}")  # 点乘运算
print(f"b1@b2: {b1@b2}")  # 矩阵乘法
print(f"sqrt(a1): {np.sqrt(a1)}")  # 对所有数依次求平方根
print(f"sin(a1): {np.sin(a1)}  cos(a1): {np.cos(a1)}")  # 对所有数依次进行三角运算
print(f"log(a1): {np.log(a1)}  power(a1): {np.exp(a1)}")  # 对所有数依次进行对数,指数运算
print(f"min(a1): {np.min(a1)}  max(a1): {np.max(a1)}")  # 返回数组中最小,最大的元素
print(f"argmin(a1): {np.argmin(a1)}  argmax(a1): {np.argmax(a1)}")  # 返回数组中最小,最大的元素所在的索引
print(f"sum(a1): {np.sum(a1)}  mean(a1): {np.mean(a1)}  median(a1): {np.median(a1)}")  # 返回数组元素的和,平均值,中位数
print(f"var(a1): {np.var(a1)}  std(a1): {np.std(a1)}")  # 返回数组中元素的方差和标准差
print(f"a1*5: {a1*5}")  # 广播,a1中所有数乘以5,产生同尺寸的新数组
# 以上函数 可以写作 a1.func()
# 在多维数组中,以上函数可以在括号内指定额外的参数 axis: axis=0对应行 axis=1对应列
print(b1[0, 1])  # 获取b1中第1行第2列的元素
print(b1[0, 0:2])  # 获取b1中第1行1~2列的元素
print(b1[::-1])  # -1为跨度,代表将数组反转
print(b1[(b1 > 3) & (b1 % 2 == 0)])  # 获取b1中筛选符合条件的数

3. SymPy:一个计算机代数系统

  • SymPy是一个Python的科学计算库,用一套强大的符号计算体系完成诸如多项式求值、求极限、解方程、求积分、微分方程、级数展开、矩阵运算等等计算问题。
  • SymPy最显著的特点是它完全由Python编写,实际上它只是Python的一个附加模块。其规模很小,可以在任何Python系统中工作。它很好地与NumPy接口实现数值处理,与Matplotlib接口实现图形输出。
import sympy as sy

# sympy内置符号
print(sy.I, sy.I**2, sy.sqrt(-1))  # 虚数i, i^2, -1的平方根
print(sy.E, sy.log(sy.E))  # 自然对数e, lne
print(sy.oo, 1/sy.oo, 1+sy.oo)  # ∞, 1/∞, 1+∞
print(sy.pi, sy.sin(sy.pi/2))  # π, sin(π/2)

# 初等运算
print(sy.log(sy.E))  # 求对数(ln)
print(sy.sqrt(-1))  # 求平方根
print(sy.root(8, 3))  # 求n次方根(8的3次方根)
print(sy.sin(sy.pi))  # 求三角函数
print(sy.factorial(4))  # 求阶乘
  • SymPy还可以表达式求值,解方程(组),求和式(Σ),求极限,求导,求(不)定积分等等,见第三条参考资料

4. 参考资料


文章中的所有代码经测试均可成功编译运行,可直接复制。具有显然结果或简单结论的代码不展示运行结果。如有问题欢迎随时交流~