4. 数据清洗与预处理实战
菌株性能试验的原始数据往往“看起来完整、用起来处处是坑”:摇瓶效价记录里夹着空单元格,发酵罐批次数据中混入了传感器跳变产生的离群点,同一株菌在不同批次被重复测定却未标注批次号,效价单位在U/mL、mg/L、μg/mL之间来回切换。若直接把这些数据丢进方差分析或回归模型,缺失值会让统计软件静默删行,异常值会拉偏均值和标准差,重复测量会被误当作独立样本而虚增自由度,单位不一致则可能让差异被放大或缩小上千倍。本节以一套模拟的链霉菌发酵性能数据为对象,完整走一遍“识别问题—选择方法—执行清洗—标准化整合—形成可分析数据集”的实战路径。
一、先摸清数据问题:四类缺陷的识别
假设我们手头有一张汇总表,字段包括:菌株编号、批次号、发酵天数、效价、生物量(DCW)、残糖、pH。共约120行记录,来自3株菌、4个批次。初步检查可发现四类问题:其一,效价列有7个空白单元格,残糖列有3个“—”;其二,某批次第5天效价记录为“3850 U/mL”,而其余同列数值在800~1200之间,明显是录入时多打了一位;其三,菌株S-02在第2、3批次各测了3个平行摇瓶,若按行统计则S-02的样本量被放大3倍;其四,部分批次效价以mg/L记录,部分以U/mL记录,二者换算关系需依据该产物比活性确定。
识别阶段建议先做三件事:用df.isna().sum()统计各列缺失数量;用df.describe()观察最小值、最大值与均值是否出现“量级异常”;用df.duplicated(subset=['菌株编号','批次号','发酵天数'], keep=False)定位重复测量行。这三步能在几分钟内把问题定位到具体行和列,避免盲目清洗。
二、缺失值处理:先判断机制,再决定策略
缺失值不能一律删除或一律填补。对效价的7个空白,先回溯原始记录:其中4个是当天未取样(完全随机缺失),2个是仪器故障导致无读数,1个是样品污染。对“未取样”的4条,若该菌株该批次其余天数数据完整,可采用同菌株同批次的时间序列线性插值;对仪器故障的2条,若前后两天效价稳定,可用前后均值填补;对样品污染的1条,由于无法确认是否代表真实低值,应标记为缺失并排除出效价分析,而不是强行填补。
残糖列的3个“—”出现在发酵后期,实际含义是“残糖低于检测限”,属于非随机缺失。此时不应填补为中位数,而应按检测限的一半(如0.5 g/L)赋值,并在数据字典中注明“低于检测限”。这一处理方式直接影响后续糖耗速率计算,必须在文档中留痕。
三、异常值判定:3σ准则与箱线图法各管一段
对效价列,先按菌株分组计算均值与标准差,用3σ准则筛查:若某点满足 |x − μ| > 3σ,则判为可疑异常。以S-01为例,其效价均值约950 U/mL、标准差约85,则上下界约为695~1205,那条3850的记录远超上界,结合原始记录确认为录入错误(多输入一位),应修正为385而非删除。3σ准则适合近似正态、样本量较大的指标,但对偏态分布或小样本容易误判。
对生物量这类可能偏态的指标,改用箱线图法更稳妥:以四分位距IQR为尺度,低于Q1−1.5×IQR或高于Q3+1.5×IQR的点视为离群。假设某批次DCW的Q1=8.2、Q3=11.6,IQR=3.4,则下界2.1、上界16.7,若出现18.5的记录,需核查是否为染菌导致生物量异常升高——这类点往往有生物学意义,不能简单删除,而应标记为“异常批次”并在分析中单独讨论或做敏感性分析。
四、重复测量的聚合:把“平行”还原为“独立单元”
重复测量是菌株数据中最容易被忽视的陷阱。S-02在第2、3批次各做了3个平行摇瓶,若直接按行进入方差分析,S-02的观测数会从2变成6,组间自由度被虚增,p值被人为压低。正确做法是先明确分析单元:若研究目标是“菌株间差异”,则每个“菌株×批次”应聚合为一个观测值,取平行样的算术均值,同时保留标准差作为批内变异指标;若研究目标是“批内一致性”,则平行样本身才是分析对象,此时不应聚合。两种目标对应两种数据集,不能混用。
聚合时建议同时生成三个字段:效价均值、批内标准差、平行样数。批内标准差过大(如超过均值的10%)的批次应回查操作记录,判断是否存在移液或培养条件波动,这类批次在后续分析中可加权处理或做敏感性分析。
五、单位统一与标准化:让数值可比
单位不一致的根源往往在记录环节。假设该产物比活性为1 mg = 1200 U,则凡以mg/L记录的效价需乘以1200换算为U/mL(若体积基准一致)。换算前必须确认分母是“每毫升发酵液”还是“每毫克菌体”,二者含义完全不同。换算后统一保留一位小数,并在数据字典中写明“效价单位:U/mL,以发酵液体积计”。
标准化还包括主键补全:为每行生成“菌株编号_批次号_发酵天数”的唯一记录号,避免后续合并时错位;将pH、残糖等数值列统一为浮点型,剔除文本型“—”;对分类字段(菌株、批次)做去空格与大小写统一。这些操作看似琐碎,却是宽表能否被统计工具正确读取的前提。
六、形成可分析数据集与验收标准
清洗完成后,输出一张分析宽表,字段建议包括:记录号、菌株编号、批次号、发酵天数、效价均值(U/mL)、效价批内标准差、生物量(g/L)、残糖(g/L)、pH、数据标记(正常/插值/低于检测限/异常待查)。验收时逐项核对:缺失值是否全部有处理依据;异常值是否均有修正或标记记录;重复测量是否已按分析单元聚合;单位是否全部统一;每列数据类型是否正确。可用一段简短脚本做最终校验:
import pandas as pd
df = pd.read_csv("strain_clean.csv")
assert df["效价均值"].notna().all(), "效价仍有缺失"
assert df["效价单位"].nunique() == 1, "单位未统一"
assert not df.duplicated(["菌株编号","批次号","发酵天数"]).any(), "仍有重复记录"
print(df.groupby("菌株编号")["效价均值"].agg(["count","mean","std"]))
完成上述步骤后,这张表才具备进入描述统计、方差分析或回归建模的条件。需要强调的是,本节涉及的数值均为教学示例,实际项目中应以原始记录和产物比活性实测值为准;清洗策略也应随缺失机制和异常成因调整,而非机械套用固定规则。