2、数据准备:载入多批次实验数据、识别批次标签、数据质量初步检查
做 LOESS 回归归一化消除批次变异,第一步就是——看看数据长什么样。 我一开始做这个的时候,总觉得算法挑得好就行,结果一上来就吃了个亏:不同批次的数据混在一起,标签还写得乱七八糟。 后来我养成了一个习惯:动手之前,先把数据拆开看,确认批次结构再走下一步。
说白了,这一步就是给你的数据“验明正身”。 哪几列是表达量?哪个列是批次编号?样本有没有缺失? 这些搞清楚,后面才能踏踏实实做回归。
2.1 载入多批次数据
假设你有三个批次的转录组表达数据,分别存在三个 CSV 文件里。 我个人喜欢用 pandas 一次性读进来,然后打上批次标签。 来,看看代码怎么写:
import pandas as pd
import numpy as np
# 模拟三个批次的文件路径
files = {
'batch_A': 'batch_a_expression.csv',
'batch_B': 'batch_b_expression.csv',
'batch_C': 'batch_c_expression.csv'
}
# 逐个读取,并加批次列
dfs = []
for batch_id, path in files.items():
df = pd.read_csv(path, index_col=0)
df['batch'] = batch_id # 添加批次标签
dfs.append(df)
# 合并全部数据
all_data = pd.concat(dfs, axis=0)
print(all_data.shape)
print(all_data['batch'].value_counts())
这段代码做了三件事:读文件、加批次列、合并。 你可能会问,为什么不在读的时候就把批次列写死? 嗯,这里要注意:批次标签一旦写错,后面的归一化全是骚操作。 我曾经因为文件名和实际批次对不上,花了两天排查,最后发现是命名规则不一致……
2.2 识别批次标签
数据加载进来后,第一件事就是确认批次标签是否完整、唯一。 你想想看,如果混合数据集里有些样本本来不属于这三个批次,归到“未知”里,那后面的 LOESS 回归就埋雷了。
我一般会先打印批次的分布,并做个快速可视化(这里不画图,只看表格)。 下面是个典型的批次分布表:
| 批次 | 样本数 | 基因数 | 缺失比例 |
|---|---|---|---|
| batch_A | 12 | 20,000 | 0.03% |
| batch_B | 15 | 20,000 | 0.05% |
| batch_C | 10 | 20,000 | 0.01% |
看到没有?三个批次的基因数一致,但样本量不均衡。 这时候你心里就该有个数:批次 C 样本少,拟合 LOESS 时带宽可能需要调整。
还有个坑:批次标签里有没有空格?大小写? 我遇到过“Batch_A”和“batch_A”两个不同的字符串,其实是同一个批次。 所以建议你统一做一次 .strip().lower():
all_data['batch'] = all_data['batch'].str.strip().str.lower()
print(all_data['batch'].unique())
2.3 数据质量初步检查
不检查数据质量就上 LOESS,等于开车不系安全带。 我个人的检查清单如下:
- 缺失值:每个基因的表达量有没有 NaN?超过 20% 缺失的基因直接剔除。
- 异常低表达:有些基因在所有样本里都接近 0,这部分数据对回归贡献很小,可以过滤掉。
- 批次内离群样本:某个样本在所有基因上的表达量都明显偏离同批次其他样本,可能是因为实验操作失误。
- 批次间的分布差异:简单画个密度图(这里不画),看批次之间中位数、四分位距有没有严重偏差。
下面这段代码帮你完成前两项检查:
# 按基因检查缺失比例
missing_ratio = all_data.drop(columns='batch').isnull().mean()
genes_to_keep = missing_ratio[missing_ratio < 0.2].index
cleaned = all_data[genes_to_keep]
# 剔除平均表达量低于 5 的基因
mean_expr = cleaned.drop(columns='batch').mean(axis=0)
low_genes = mean_expr[mean_expr < 5].index
cleaned = cleaned.drop(columns=low_genes)
print(f"保留基因数: {cleaned.shape[1] - 1}") # 减掉 batch 列
检查完数据质量后,最好生成一个简单的质量报告摘要,方便存档和复现。 你可以用下面的格式记录:
质量报告摘要
-----------------
原始样本数: 37
原始基因数: 20000
缺失率 > 20% 的基因: 104(已剔除)
平均表达量 < 5 的基因: 318(已剔除)
最终样本数: 37
最终基因数: 19578
批次分布: batch_a=12, batch_b=15, batch_c=10
到这里,数据准备好了,批次标签明确了,质量也把过一遍了。 接下来才是真正的 LOESS 回归归一化——不过那是下一章的事。