当前位置:首页>python>Python 入门第一课:别怕 Data Parsing,它就是给数据“相亲配对”

Python 入门第一课:别怕 Data Parsing,它就是给数据“相亲配对”

  • 2026-10-11 08:04:45
Python 入门第一课:别怕 Data Parsing,它就是给数据“相亲配对”

今天我们来聊一个vibe coding时代药化同学迟早会遇到的东西:
Data Parsing,数据解析。我愿意称之为数据高级定制
听起来很高级,好像一打开就要召唤计算机大神。其实说白了,它就是:
> 把乱七八糟的 Excel 数据,整理成机器能看懂的一张干净大表。
这件事在药物研发里特别常见。比如你手上有三张表:

1. 药物的物理化学性质

2. 药物对细胞系的 IC50

3. 细胞系的 mutation 信息

你想做 Random Forest,预测药物对不同细胞系的效果。
问题是,这些信息一开始不在一张表里。就像实验室里三个人各拿一半真相:
A 同学说:“我知道这个药物的 ALogP。”
B 同学说:“我知道这个药物对 A549 的 IC50。”
C 同学说:“我知道 A549 有哪些 mutation。”
Random Forest 老师坐在那里说:
> “你们能不能先把话说完整?一行里面同时告诉我 cellline、drug name、IC50、mutation、分子描述符,不然我怎么学习?”
所以 Data Parsing 的本质就是:
> 把分散的信息拼成一张完整的科研身份证表。
---

 一、为什么 AI 会写代码,我们还要手搓?

现在流行vibe coding
你告诉 AI 想做什么,AI 帮你写代码。
听起来很美好,像是:
> “AI,帮我把三个 Excel merge 一下,再训练 Random Forest。”
> “好的主人,模型已经训练完成。”
但是现实里常常是:
```pythonKeyError: 'drug_name'```
然后你就开始怀疑人生。
这就像你让学生帮你配 buffer,他说“老师我配好了”,结果 pH 是 14。
AI 写代码很快,但你必须知道它到底在干什么。
尤其是 Python 和 Pandas,刚开始一定要 **手搓**。
不是为了显得很苦,而是为了建立“代码手感”。
什么叫手感?
就是你看到:
```pythonKeyError: 'drug_name'```
你马上知道:
> 哦,不是 Python 坏了,是我的表里没有叫 `drug_name` 的 column。
这种感觉,比背十遍教程有用。
---

## 二、我们的真实问题:column 名字不一致

我们本来想写:
```pythonlearning["drug_name"]```
结果 Python 报错:
```text
KeyError: 'drug_name'
```
为什么?
因为真实的 `learning` 表里 column 是:
```python['cellline', 'drug', 'ic50(ln)']```
注意,它叫:
```pythondrug```
不是:
```pythondrug_name```
而另一个药物描述符表 `drug_desc` 里面叫:
```pythonDrug_name```
这就像一个人身份证上叫“张三”,另一个表里叫“老张”。
你让 Python 按“张三”找“老张”,它当然说:
> “找不到,别为难我。”
所以第一步就是统一名字。
---

 三、第一步:导入工具

```python#导入 pandas,用来处理表格数据#可以把 pandas 理解成 Python 版的 Excel,但是更适合自动化和大规模数据处理import pandas as pd#导入 numpy,用来处理数字、矩阵、缺失值等#后面做机器学习时也经常会用到import numpy as np```
如果你还没有安装这些包,在 Mac Terminal 里运行:
```bashpython3 -m pip install pandas numpy openpyxl scikit-learn```
如果你在 Jupyter Notebook 里运行,可以写:
```python!pip install pandas numpy openpyxl scikit-learn```
---

四、第二步:读取三个 Excel

```python#读取药物描述符数据#这个表里通常有 drug_name、ALogP、ALogP2、nAcid 等分子物理化学特征drug_desc = pd.read_excel("2d_str_PADEL_norm_modify_GDSC_final.xlsx")#读取学习数据#这个表里有 cellline、drug、IC50 信息learning = pd.read_excel("learning_data.xlsx")#读取 mutation 数据#这个表里有 mutation 信息,列名通常是不同 cell linemutation = pd.read_excel("match_count2.xlsx")```
读完以后,不要急着 merge。
先看一眼表格长什么样。
```python#查看每个表的大小#shape 会返回:多少行,多少列print("drug_desc:", drug_desc.shape)print("learning:", learning.shape)print("mutation:", mutation.shape)#查看每个表前 5 行print(drug_desc.head())print(learning.head())print(mutation.head())```
这一步像实验前先看标签。
别一上来就加试剂,先确认瓶子里到底是什么。
---

五、第三步:清理 column 名字

Excel 里最讨厌的东西之一是隐藏空格。
比如:
```textDrug nameDrug Namedrug namedrug name```
人眼看差不多,Python 看起来全是不同东西。
所以我们先写一个清洁函数。
```python#定义一个函数,用来清理表格的 column 名字def clean_columns(df):#df.columns 表示这个表的所有列名df.columns = (df.columns.astype(str)#把所有列名转成字符串,避免有些列名是数字或 NaN.str.strip()#去掉列名前后的空格.str.lower()#全部变成小写.str.replace(" ", "_")#把空格变成下划线.str.replace("-", "_")#把短横线变成下划线.str.replace(".", "_", regex=False)#把点号变成下划线)return df```

然后应用到三个表:
```python#清理三个表的 column 名字drug_desc = clean_columns(drug_desc)learning = clean_columns(learning)mutation = clean_columns(mutation)```
检查一下:
```python#打印 learning 表的所有列名print("learning columns:")print(learning.columns.tolist())#打印 drug_desc 表前 10 个列名print("drug_desc columns:")print(drug_desc.columns[:10].tolist())#打印 mutation 表前 10 个列名print("mutation columns:")print(mutation.columns[:10].tolist())```
这一步很重要。
很多初学者一报错就怀疑“是不是我电脑不行”。
其实 80% 的情况只是 column 名字没对上。
---

六、第四步:把 learning 表的列名改成统一格式

我们检查后发现:
```pythonlearning.columns.tolist()```
结果是:
```python['cellline', 'drug', 'ic50(ln)']```
但是后面我们希望统一使用:
```pythoncelllinedrug_nameic50```
所以要改名。
```pythonrename learning columns#把 learning 表里的 drug 改成 drug_name#把 ic50(ln) 改成 ic50#这样后面 merge 和建模更方便learning = learning.rename(columns={"drug": "drug_name","ic50(ln)": "ic50"})```#检查一下:```pythonprint(learning.columns.tolist())```
希望看到:
```python['cellline', 'drug_name', 'ic50']```
如果看到了,说明这一关过了。
---

七、第五步:清理关键列里的文字

column 名字清理完了,还要清理内容。
比如药名可能是:
```textGefitinib Gefitinibgefitinib```
这些对人来说一样,对 Python 来说可能不一样。
所以我们要处理 `drug_name` 和 `cellline`。
```pythonclean key values#把 drug_name 转成字符串,然后去掉前后空格learning["drug_name"] = learning["drug_name"].astype(str).str.strip()#把 cellline 转成字符串,然后去掉前后空格learning["cellline"] = learning["cellline"].astype(str).str.strip()#drug_desc 表里的 drug_name 也要做同样处理drug_desc["drug_name"] = drug_desc["drug_name"].astype(str).str.strip()```
为什么这一步重要?
因为 merge 就像相亲。
两边名字必须对得上。
```textGefitinib```
和
```text Gefitinib```
在 Python 眼里不是同一个人。
一个多余空格,就能拆散一段美好姻缘。
---

八、第六步:第一次 merge,给 IC50 配上药物性质

现在我们有:

learning 表

```textcellline | drug_name | ic50```

drug_desc 表

```textdrug_name | nacid | alogp | alogp2 | ...```
我们要按照 `drug_name` 合并。
```pythonfirst merge#以 learning 为主表#根据 drug_name 去 drug_desc 里找对应的分子描述符merge1 = pd.merge(learning,#左边主表,保留所有 learning 里的行drug_desc,#右边表,提供药物 descriptoron="drug_name",#按 drug_name 这一列进行匹配how="left"#左连接,learning 里的数据全部保留)```
这里 `how="left"` 很关键。
它的意思是:
> learning 表里的每一条 IC50 数据都保留,然后去 drug_desc 表里找药物特征。
如果找到了,就补上。
如果找不到,就变成 `NaN`。
就像你拿着学生名单去找成绩单。
学生名单上的人不能丢,找不到成绩就先空着。
---

九、第七步:检查第一次 merge 是否成功

```python打印三个表的大小print("learning:", learning.shape)print("drug_desc:", drug_desc.shape)print("merge1:", merge1.shape)```
然后看关键几列:
```python查看 merge 后的结果如果能看到 nacid、alogp、alogp2,说明药物 descriptor 已经成功加进来了print(merge1[["cellline", "drug_name", "ic50", "nacid", "alogp", "alogp2"]].head())```
如果输出类似:
```textcellline drug_name ic50 nacid alogp alogp2A549 Gefitinib 1.23 0 3.1 9.61H1975 Erlotinib 0.89 0 2.8 7.84```
恭喜,第一段路走通了。
这时候你的数据已经从:
```text这个药物对这个细胞的 IC50```
升级成:
```text这个药物对这个细胞的 IC50,同时这个药物有哪些物理化学性质```
Random Forest 已经开始微笑了。
---

十、完整代码,适合初学者复制运行

# =========================# Step 1. Import libraries# =========================# pandas 用来处理表格import pandas as pd# numpy 用来处理数字和矩阵import numpy as np# =========================# Step 2. Read Excel files# =========================# 药物物理化学描述符表drug_desc = pd.read_excel("2d_str_PADEL_norm_modify_GDSC_final.xlsx")# IC50 学习数据learning = pd.read_excel("learning_data.xlsx")# mutation 数据mutation = pd.read_excel("match_count2.xlsx")# =========================# Step 3. Clean column names# =========================def clean_columns(df):    """    这个函数用来清理 column 名字。    目的:    1. 去掉前后空格    2. 全部变小写    3. 把空格、横线、点号换成下划线    这样可以减少 KeyError。    """    df.columns = (        df.columns        .astype(str)        .str.strip()        .str.lower()        .str.replace(" ", "_")        .str.replace("-", "_")        .str.replace(".", "_", regex=False)    )    return df# 对三个表都进行 column 清理drug_desc = clean_columns(drug_desc)learning = clean_columns(learning)mutation = clean_columns(mutation)# =========================# Step 4. Check real columns# =========================# 打印真实列名# 初学者一定要养成这个习惯print("learning columns:")print(learning.columns.tolist())print("drug_desc first 10 columns:")print(drug_desc.columns[:10].tolist())print("mutation first 10 columns:")print(mutation.columns[:10].tolist())# =========================# Step 5. Rename learning columns# =========================# 你的 learning 表真实列名是:# cellline, drug, ic50(ln)# 但是为了后面统一处理,我们改成:# cellline, drug_name, ic50learning = learning.rename(columns={    "drug": "drug_name",    "ic50(ln)": "ic50"})# 再检查一次,确认改名成功print("learning columns after rename:")print(learning.columns.tolist())# =========================# Step 6. Clean key values# =========================# 清理 drug_name 里的空格learning["drug_name"] = learning["drug_name"].astype(str).str.strip()# 清理 cellline 里的空格learning["cellline"] = learning["cellline"].astype(str).str.strip()# 清理 drug_desc 表里的 drug_namedrug_desc["drug_name"] = drug_desc["drug_name"].astype(str).str.strip()# =========================# Step 7. First merge# =========================# 把 learning 和 drug_desc 按 drug_name 合并# learning 提供 cellline、drug_name、ic50# drug_desc 提供 nacid、alogp、alogp2 等药物描述符merge1 = pd.merge(    learning,    drug_desc,    on="drug_name",    how="left")# =========================# Step 8. Check merge result# =========================print("learning:", learning.shape)print("drug_desc:", drug_desc.shape)print("merge1:", merge1.shape)# 查看前几行,确认 descriptor 已经合并进来print(    merge1[        ["cellline", "drug_name", "ic50", "nacid", "alogp", "alogp2"]    ].head())

---

## 十一、这段代码背后的药化意义

这一段不是单纯学 Python。
它其实是在做药物研发里的一个核心动作:
```text药物结构信息 + 细胞背景信息 + 活性数据```
先拼起来,才有可能让机器学习模型找规律。
比如 Random Forest 后面可能会学到:
```text高 ALogP 的药物,在某些 mutation 背景下 IC50 更低```
或者:
```text某类 PubChem fingerprint 特征和某些细胞系敏感性有关```
再往后,你就可以做:
```textfeature importancedrug response predictioncell line sensitivity analysismutation based drug response model```
听起来就像 AI 药物研发了。
但地基还是这一句:
```pythonpd.merge(...)```
别小看它。
很多 AI 项目不是死在模型上,而是死在数据没拼对。
---

十二、给 0 基础学生的一句话

刚开始学 Python,不要怕报错。
`KeyError` 不是骂你。
它只是在说:
> “老师,这个 column 名字我真没找到。”
你要做的不是紧张,而是运行:
```pythonprint(df.columns.tolist())```
看一眼真实列名。
这就是手搓代码的价值。
AI 可以帮你写,但你要知道哪里可能错。
就像药化里 AI 可以帮你生成分子,但你还是要知道这个结构能不能合成,会不会太油,会不会像一块会走路的凡士林。
Vibe coding 很好,但基础手感不能丢。
代码不是魔法,代码更像实验。
每一步都要看结果,每一步都要确认。
今天你学会的其实不只是 `rename` 和 `merge`,而是一个科研数据处理的基本姿势:
> 先看清数据,再统一名字,再清理内容,最后合并。
这就是 Data Parsing 的第一课。

最新文章

随机文章