
本文详解如何正确读取zinc数据库提供的smi格式文件(以空白符分隔的两列文本),并使用pandas直接解析为结构化dataframe,避免手动逐行读取导致的换行符残留、列错位等问题。
本文详解如何正确读取zinc数据库提供的smi格式文件(以空白符分隔的两列文本),并使用pandas直接解析为结构化dataframe,避免手动逐行读取导致的换行符残留、列错位等问题。
ZINC数据库导出的 .smi 文件并非纯SMILES列表,而是一种类CSV格式:首列为SMILES字符串,第二列为化合物ID(如ZINC ID),两列之间以一个或多个空格或制表符分隔。若直接用 f.readlines() 读取再构造DataFrame,会导致每行末尾保留 \n 换行符,且无法自动拆分ID列,最终数据混乱、不可用。
✅ 正确做法是——直接使用 pandas.read_csv() 配合正则分隔符 sep='\s+'(匹配一个或多个空白字符),让pandas自动完成解析与对齐:
import pandas as pd
# 直接读取SMI文件,按空白符分割(兼容空格/制表符)
df = pd.read_csv('substances.smi', sep='\s+', header=None, engine='python')
# 标准化列名:SMILES + ID
df.columns = ['SMILES', 'ID']
# 可选:去除SMILES两端空格及换行影响(read_csv通常已处理,但可双重保险)
df['SMILES'] = df['SMILES'].str.strip()
df['ID'] = df['ID'].str.strip()
print(df.head())
输出示例:
SMILES ID 0 N[C@H](CCc1ccc(N(CCCl)CCCl)cc1)C(=O)O ZINC000016090786 1 N[C@@H](CCCc1ccc(N(CCCl)CCCl)cc1)C(=O)O ZINC000002033385 2 N[C@H](CCCc1ccc(N(CCCl)CCCl)cc1)C(=O)O ZINC000001763088
⚠️ 注意事项:
- 若SMI文件不含ID列(仅单列SMILES),read_csv 会报错“Expected X columns, got Y”。此时应显式指定 usecols=[0] 并设 header=None,再重命名列;
- 避免使用 skiprows 或 nrows 参数误删首行——ZINC SMI文件无表头行,所有行均为有效数据;
- 大型SMI文件(百万级分子)建议添加 dtype={'ID': 'string'} 提升读取效率并防止数字型ID被误转为float;
- 后续进行化学信息学操作(如RDKit分子构建)前,推荐先用 df['SMILES'].dropna().str.strip() 清洗无效空值。
掌握此方法后,你即可无缝对接ZINC、ChEMBL等主流数据库的SMI资源,快速构建可分析的化合物DataFrame,为激酶靶点关联筛选、QSAR建模等下游任务奠定坚实数据基础。











