「BUAA Python Programming」Notes
Part 0 前言
尽管Python暑期课已经告一段落,但是和Python的旅程并没有迎来结束Python在做胶水方面实在太强大辣,因此,在这里开一篇新博客记录一些常用的笔记备忘。
Part 1 json处理
Python的json
库提供了强大的json处理工具,在工作中十分常用。
读取json
json.load
从文件中读取json。
e.g.
1 2 3 4
| file_dir = "./data.json" with open(file_dir, 'r', encoding='utf-8') as f: s = json.load(f) print("Yes")
|
Part 2 字符串处理
strip()
移除字符串头尾指定字符(通常为空格和换行符)
e.g.
replace()
以指定字符串替换字符串中指定子串,还可以用来实现删除字符串中全部指定子串。
e.g.
1 2 3 4 5
| s = "Hello, BUAA!\nHello, TsingHua\n" s1 = s.replace("Hello", "Wow") print("s1 : \n" + s1) s2 = s.replace("Hello", "") print("s2 : \n" + s2)
|
output:
1 2 3 4 5 6 7
| s1 : Wow, BUAA! Wow, TsingHua
s2 : , BUAA! , TsingHua
|
Part 3 文件处理
python提供了强大的文件处理能力,掌握这些接口可以方便地造轮子(bushi)。
判断文件存在与删除
1 2 3 4 5
| import os flag_path = os.path.exists(path) flag_file = os.path.isfile(file_name) if flag_path: os.remove(path)
|
文件读写操作
参考:python 写入文件 wb_一篇搞懂python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)
Part 4 加密
在WEB开发等工作中,对于密码等涉密信息加密是常见的操作,python提供了简洁优雅的加密函数与接口。
md5加密
1 2 3 4 5 6
| import hashlib def md5_encode(s): s_new = s hl = hashlib.md5() hl.update(s_new.encode("utf-8")) return hl.hexdigest()
|
Part 5 Matplotlib绘图
在写论文时,经常会遇到需要绘制示意图的情况。对于科研绘图,网络上有各种建议,这里记录使用Python绘图的笔记。
相比于Visio、PowerPoint等绘图方式,Python绘图的突出优点包括图片由代码生成,具有高可复用性并且对手残友好,且其导出的svg矢量图也十分适合论文排版;对于有一定代码经验和基础的同学较为友好,语法较为简单;数学方面的图表支持较为强大,对于坐标等对精度有较高要求的绘制可以通过代码精确控制,避免手绘的随机性。
以下是一些质量较高的参考资料:
Matplotlib简介
matplotlib是2D绘图领域使用较为广泛的套件,性能强大,语法简单。更多介绍可以参考Matplotlib 教程-Runoob
导入相关包
1 2 3
| import matplotlib.pyplot as plt import numpy as np import matplotlib
|
设置支持中文字体
matplotlib.rc(‘font’, family=’FangSong’) # 这里以仿宋字体为例,其他支持的字体可以自行搜索
更多字体设置,可以参考彻底解决Python里matplotlib不显示中文的问题-ZhiHu
设置坐标轴刻度显示范围
1 2 3
| plt.xlim(-120, 120) plt.ylim(-120, 120)
|
figure可以类比“纸”;axes可以类比“区域”。更详细的介绍可以参考Matplotlib中的plt和ax都是啥?-ZhiHu
1
| fig, ax = plt.subplots(figsize=(8, 8))
|
预览
保存图片
1 2
| plt.savefig("img.svg", dpi=300, format="svg")
|
标记文字
满足需要在特定位置显示特定文字的需求
1 2 3 4
| x1, y1 = 3, 4 text = r"$\alpha _1$" ax.text(x1, y1, text)
|
绘制线
这里的绘制线是基础行为,后续的直线绘制、圆绘制、曲线绘制等都基于此
1 2 3 4 5
| x1, y1 = 1, 2 x2, y2 = 4, 5 ax.plot([x1, x2], [y1, y2], color='black', linestyle='-', zorder=1, label=r'example line')
|
由于上文中对plt和ax的介绍,我们后续会更多的采用ax来使代码更具扩展性
label参数支持 $\LaTeX$数学公式,可以使用$$编辑并显示行内公式
关于color的更多资料,可以参考Matplotlib 绘图线-Runoob
关于linestyle的更多资料,可以参考Matplotlib 绘图线-Runoob
关于zorder的更多资料,可以参考Zorder演示-Zorder中文网
绘制点
1 2 3
| x3, y3 = 4, 2 ax.scatter(x3, y3, color='black', color='black', linewidth=4, zorder=20, marker='.', label='example point')
|
关于marker的更多资料,可以参考Matplotlib 绘图标记-Runoob
绘制箭头
1 2 3 4
| x1, y1 = 2, 3 x2, y2 = 7, 6 ax.arrow(x1, y1, x2 - x1, y2 - y1, head_width=4, head_length=4, color='black')
|
关于arrow的更多资料,可以参考matplotlib.axes.Axes.arrow()函数
绘制圆
1 2 3 4 5 6
| theta = np.linspace(0, 2 * np.pi, 200) circle_x = 100 * np.cos(theta) circle_y = 100 * np.sin(theta) fig, ax = plt.subplots(figsize=(8, 8)) ax.plot(circle_x, circle_y, color="black", linewidth=1, label=r'理想编队队形, $R=100m$', linestyle='--')
|
以圆弧绘制角符号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| def draw_angle_with_points(x0, y0, x1, y1, x2, y2, r=10, dx=0, dy=0, text=None, show_text=False): if y1 > y0: x1_high, y1_high = x1, y1 x1_low, y1_low = x0, y0 else: x1_high, y1_high = x0, y0 x1_low, y1_low = x1, y1 delta_y1 = y1_high - y1_low delta_x1 = x1_high - x1_low angle1 = np.arctan(delta_y1 / delta_x1) if y2 > y0: x2_high, y2_high = x2, y2 x2_low, y2_low = x0, y0 else: x2_high, y2_high = x0, y0 x2_low, y2_low = x2, y2 delta_y2 = y2_high - y2_low delta_x2 = x2_high - x2_low angle2 = np.arctan(delta_y2 / delta_x2) draw_angle(x=x0, y=y0, r=r, st=angle1, ed=angle2, dx=dx, dy=dy, text=text, show_text=show_text)
|
思路其实不复杂:给出圆心、弧的起始角度、弧的终点角度即可计算出圆
图层
有时候会遇到希望某个图形显示在其他图形上面或下面的需求,这时候可以利用库提供的图层属性,使用类似PR的逻辑处理图形之间的关系。
在上文中其实已经有所介绍,即使用zorder
设置图层级别,更详细的使用方法可以参考Zorder演示 | Matplotlib 中文
图片比例
笔者在应用中发现,可能会遇到明明应该是长宽比1:2,但是看起来却很不像,这可能是因为绘图时自动根据布局进行调整。我的解决办法是在四边较远的地方都放置透明且图层级别最低的点,这样“撑”起了图的正确比例。
Part 6 Numpy科学计算
Numpy简介
近年来,Matlab的使用在内地越来越被限制,在具有敏感背景的高校更是如此。在这样的环境下,使用python是优秀的选择,BUAA《数学建模》课程与数学建模国赛都更推荐python。其中,Numpy库起到了重要的作用。
NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。更多的介绍,可以参考NumPy 教程-Runoob
导入相关包
numpy社区推荐导入时使用:
矩阵$\times$向量
@
运算符用于矩阵和向量之间的乘法,其中第二位运算数会被转置。
e.g.:
1 2 3
| x0 = np.array([2,1,1]) mat = np.array([[0.6, 0.1, 0.3], [0.1, 0.9, 0], [0.3, 0, 0.7]]) ans = mat @ x0
|
Part 7 处理Excel
参考:python实现——处理Excel表格(超详细)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| excel_name = excel_file.name
mobile = os.path.splitext(excel_name)[0]
ext = os.path.splitext(excel_name)[1]
excel_name = f'avatar-{mobile}{ext}'
excel_path = os.path.join(EXCEL_UPLOAD, excel_name)
with open(excel_path, 'wb') as fp: fp.write(excel_file.read())
os.chdir(EXCEL_UPLOAD) workbook = openpyxl.load_workbook(excel_name) sheet = workbook['Sheet1'] ret_json = [] n = 0 for i in sheet.iter_rows(): key = 'None' value = 'None' for j in i: print('i = ' + str(i) + ' j = ' + str(j) + ' value = ' + str(j.value)) if key == 'None': key = str(j.value) else: value = str(j.value) ret_json.append({key: value})
|
Part 8 自定义类与排序
e.g.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class UserGoodClass(object): def __init__(self, id, name, price, seller_id, maker, picture, description, date, shelf_life, like, num): self.id = id self.name = name self.price = price self.seller_id = seller_id self.maker = maker self.picture = picture self.description = description self.date = date self.shelf_life = shelf_life self.like = like self.num = num self.value = 5 * self.num + 3 * like def __lt__(self, other): return self.value > other.value
|
1 2 3 4 5 6
| goodObj = UserGoodClass(id=good_id, name=good.name, price=good.price, seller_id=good.seller_id, maker=good.maker, picture=good.picture, description=good.description, date=good.date, shelf_life=good.shelf_life, like=like, num=num)
ret_list.append(goodObj)
ret_list.sort()
|
Part 9 yield
参考:
yield
是 python 中的关键字,用于定义生成器函数。当一个函数中使用了 yield
函数时,它即被标记为生成器函数,而非普通的函数(这里笔者理解普通函数的行为是调用后即进入函数逐条语句执行)。生成器函数的执行不会像普通函数一样立即返回结果,而是在迭代器调用时逐步生成数据,并在调用 yield
时暂停执行并保存当前状态。yield
的优势在于处理大量数据,可以按需生成数据,无需一次性加载所有数据到内存中,在深度学习中比较常用。
e.g.
1 2 3 4 5 6 7 8 9 10 11 12
| def data_iter(batch_size, features, labels): num_examples = len(features) indices = list(range(num_examples)) random.shuffle(indices) for i in range(0, num_examples, batch_size): batch_indices = torch.tensor( indices[i: min(i + batch_size, num_examples)]) yield features[batch_indices], labels[batch_indices]
|
This is copyright.