如何在循环中将字典插入DataFrame并设字典键为列名?
解决方案:从SMILES生成RDKit描述符DataFrame
直接收集所有描述符字典再一次性转为DataFrame是最高效的方式,比循环内逐行追加到DataFrame性能好得多,同时还能处理无效SMILES的情况。
完整实现代码
import pandas as pd from rdkit import Chem from rdkit.Chem import Descriptors # 输入示例数据 data = [ {"ID": "ZINC000000793995", "SMILES": "COc1cccc(CNc2ccc(S(=O)(=O)Nc3nccs3)cc2)c1O"}, {"ID": "ZINC000000579895", "SMILES": "COc1cc(-c2ccc(O)cc2)c(OC)c(O)c1-c1ccc(OCC=C(C)C)c(O)c1"}, {"ID": "ZINC000000532501", "SMILES": "O=C(O)c1cc2cc(Cl)ccc2o1"} ] df = pd.DataFrame(data) # 初始化列表存储每个分子的描述符字典 descriptors_list = [] for smiles in df["SMILES"]: # 将SMILES转为RDKit Mol对象 mol = Chem.MolFromSmiles(smiles) if mol is not None: # 计算所有分子描述符,得到字典 desc_dict = Descriptors.CalcMolDescriptors(mol) descriptors_list.append(desc_dict) else: # 若SMILES解析失败,插入空字典保证行数对齐 descriptors_list.append({}) # 将字典列表转为DataFrame,自动用字典键作为列名 descriptors_df = pd.DataFrame(descriptors_list) # 可选:合并原数据的ID列,方便关联分子信息与描述符 final_df = pd.concat([df[["ID"]], descriptors_df], axis=1) # 查看结果示例 print(final_df[["ID", "MaxAbsEStateIndex", "qed"]].head())
关键说明
- 性能优化:用列表收集所有描述符字典后再转DataFrame,避免循环中
df.append()的低效操作(pandas中append本身就是低效的,数据量大时差距明显) - 容错处理:加入
mol is not None的判断,跳过无法解析的SMILES,同时插入空字典保证最终DataFrame的行数与原数据一致 - 列名自动匹配:
pd.DataFrame(descriptors_list)会自动把所有字典的键合并为列名,缺失值会填充为NaN
输出效果
生成的final_df包含原数据的ID列,以及210个RDKit分子描述符列(如MaxAbsEStateIndex、qed等),每一行对应一个分子的描述符数值。
内容的提问来源于stack exchange,提问作者Michael Testini
相关产品推荐
相关产品推荐

