使用大模型辅助Python编程的示例——excel数据生图
介绍
大模型可以提供现成的代码块,根据这些代码块,可以减少我们程序设计的难度,快速学习新的Python模块并加以运用。下面是对Python的简单介绍,可以快速了解Python。
Python中最重要的概念就是模块,可以把编程理解为乐高积木,模块就好比其它人组装好的一些积木块,就好比一个小房子,小房子的功能是可以让小人住进去。乐高积木会自带一些基本的块,小人可以算是一种基本的块。但是搭建小房子很麻烦,所以可以购买现成的小房子,避免我们自己去组装。
同样的,Python社区里有很多人已经编写好的代码,这些代码被封装成模块。通过下载模块,就可以在基础Python的环境中更方便的实现新的功能。大部分模块都是开源免费的。模块里面又会有封装好的类或函数。函数是实现特定功能的代码,具有函数名和传入参数。有的函数会有返回值,有的函数没有返回值。
例如function(x, y)可以根据传入参数x和y来实现某些功能,例如利用x和y进行计算。有时x,y可能是比单个数更复杂的数据类型,比如数组。如果两个数组长度相等,可以把x,y看成一系列点的横纵坐标。我们可以设计函数来绘制这些点的折线图。
Python可以直接输出这个折线图,或者把这个折线图以多维数组的形式,储存在一个变量里,这个变量可以作为函数的返回值被传出。在这个情况下,我们可以用另一个变量去接收这个返回值,譬如image = function(x, y)。
Python中的类,就是面向对象编程中的对象,简单来说,类会具有一些属性和方法,属性可以理解为类中的变量,方法可以理解为类中的函数。通常来说,类的方法主要实现了对类的属性的操控。类的属性可以像普通的变量一样使用,类的方法也可以像普通的函数一样使用。
本质上,面向对象编程和面向过程编程是相通的,只是面向对象编程需要花费更多时间去设计类,而类的设计在复杂的程序中可以简化程序的编写和理解。
这里面包含的哲学和现实世界亦是相同的,世间处处有对象,也就有了相应的属性和方法。一个对象影响其它对象就需要方法的运行,需要对属性的操纵。而每一个对象怎么去运行方法,怎么去被其它对象影响,受到算法的控制,自然中的算法就是物理法则,时刻控制着事件的发生。
示例
在这篇文章中,遇到任何问题,你都可以求助大模型,例如ChatGPT。在本文中也会使用ChatGPT来辅助编程。
虚拟环境创建
首先,我们会安装conda来管理Python环境。
然后我们需要创建一个环境来完成我们今天的任务。
例如我们可以生成一个名为plot的虚拟环境。plot是一个可以更换的名字。
1. 打开命令行(例如powershell)
2. 创建虚拟环境plot,在命令行中,我们输入conda create -n plot python=3.11
准备工作
通常我会使用vs code作为编辑器书写代码。但使用jupyter是学习Python的一个比较好的方式,并且更适合科研数据分析场景。在这里我会介绍如何使用jupyter进行程序编写和调试。
1. 激活虚拟环境plot,在命令行中,我们输入conda activate plot
2. 安装jupyter lab或jupyter notebook。在中国可以使用这条命令,pip install jupyter lab -i https://pypi.tuna.tsinghua.edu.cn/simple
pip是python自带的模块管理器或者包管理器,模块(module)和包(package)基本是同一个东西。有些模块会用到其它模块(就好比小房子模块可能需要沙发模块、电视机模块),所以模块管理器会解决这些依赖问题,把所有需要的模块都下载到环境中。
conda install命令也可以安装模块,在这里,为了减少学习负担,我们可以统一使用pip来进行Python的模块安装。
这条命令中的-i及其后面的内容是使用清华源来安装,在国内会更快。
3. 更改自己的目录到你的程序项目的目录,例如我的目录是E:\Programming\plot。这个地址可以在资源管理器的上方面包屑导航中右键选择”将地址复制为文本“实现。然后在命令行里输入cd E:\Programming\plot
其中,cd是change directory的缩写。
4. 启动jupyter lab。输入jupyter lab即可。这条命令会在浏览器里打开jupyter的图形界面。
5. 通过点击创建一个Python的Notebook,创建之后可以对其进行重命名。
1. 接下来可以编程了,我们写下我们的数据情况和需求:
数据情况:
- 一个excel表格,第一行是列名,第一列是时间序列,从0开始,间隔为1,单位是1秒。此后每一列都是一个细胞的荧光强度数据,第一行是细胞的编号
需求:
- 使用Python语言
- 在jupyter里运行程序,将不同的功能合理地分块。
- 将每一个细胞的荧光强度在时间上变化的曲线图像生成出来
- 所有图像的纵坐标尺度相同,这个纵坐标尺度的范围必须大于最大的荧光强度值,默认是最大的荧光强度值,然后用户可以在jupyter里可以指定纵坐标尺度的范围。
- 细胞编号(即细胞数据中的每一列的第一行)要在图像中标注
- 横坐标名为”Time(s)“,纵坐标名为”Intensity of Fluorescence“
- 可以保存这些图像到目录/images/excel_name中,其中excel_name是表格的名称,然后图像的名称就是对应细胞的编号。
虽然我们可能不会编程或是很难一下子构建这种复杂度的程序,但我们可以借助大模型来辅助我们。
这里是我和ChatGPT的对话内容:点我
2. 可以看到我们需要在程序最开始导入三个模块,其中os是Python自带的模块,另外两个需要pip安装。在对话中,你可以看到我直接让ChatGPT给我安装的命令。
由于jupyter lab在运行时,命令行是不能被使用的,其中一个解决方法是在jupyter lab里打开一个terminal。
然后输入安装模块的命令:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas matplotlib
pandas读取excel需要依赖openpyxl,额外装一下openpyxl。
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple openpyxl。
4. 继续扩增代码块。并且进行审计(也就是检查代码)。这里我没有审计,直接复制ChatGPT给出的代码,结果报错了。这是非常常见的现象。通常来说必须要阅读代码,理解后再运行。这里的问题是,数据文件的目录和存储目录没有正确的指定。
5. 由于报错和实现的问题,我们理解并修改代码。如果有理解困难就询问ChatGPT。这个程序有很多需要修改的地方。主要是只执行一次的代码不需要使用函数封装,特别是在jupyter里。
同时没有用户输入,有用户输入可以减少对原代码的修改。
可以把代码保存为main.py(文件名可以修改)文件来运行,在plot虚拟环境中使用python main.py来运行。
最终写好的代码如下:
# 导入模块
import pandas as pd
import matplotlib.pyplot as plt
import os
# 设置路径
while True:
filename = input('输入数据表格的文件名(不需要后缀):')
appendix = '.xlsx'
file_path = filename + appendix
save_path = 'images/' + filename
if os.path.exists(file_path):
break
else:
print("文件不存在,请重新输入。")
# 读取表格
df = pd.read_excel(file_path) # df是dataframe的意思
# 是否储存数据
save_flag = True
# 储存数据相关的代码
if save_flag:
if not os.path.exists(save_path):
os.makedirs(save_dir)
# 是否自定义纵坐标尺度
yscale_flag = False
# 纵坐标尺度相关的代码
y_max = df.iloc[:, 1:].max().max() # 读取最大值
if yscale_flag:
while True:
y_max_diy = input(f"输入一个大于等于{ymax}的值作为纵坐标尺度上界")
if y_max_diy >= y_max:
break
y_scale = (0, y_max_diy)
else:
y_max = df.iloc[:, 1:].max().max()
y_scale = (0, y_max * 1.1) # 默认为最大荧光强度值的1.1
print(f"纵坐标尺度为:{y_scale}")
# 横坐标尺度相关代码
x_scale = (df.iloc[0,0],df.iloc[-1,0])
print(f"横坐标尺度为:{x_scale}")
# 获取第一列(时间序列)的列名
time = df.columns[0]
# 获取细胞编号列表
cell_ids = df.columns[1:]
# 绘制每个细胞的曲线
for cell_id in cell_ids:
plt.figure() # 创建一个figure
plt.plot(df[time], df[cell_id], color='black') # 绘制曲线,指定颜色
plt.xlabel('Time(s)') # 横坐标标签
plt.ylabel('Intensity of Fluorescence') # 纵坐标标签
plt.title(cell_id) # 图名
plt.ylim(y_scale) # 纵坐标尺度
plt.xlim(x_scale) # 横坐标尺度
plt.grid(True) # 画网格
if save_flag:
plt.savefig(os.path.join(save_path, f'{cell_id}.png'))
plt.close() # close了就不会在jupyter里显示了
评论
发表评论