You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:从分子式字符串提取原子计数并存储到DataFrame

嘿,我来帮你搞定这个分子式原子计数提取的问题!

你遇到的问题主要出在两个地方:一是str.extract返回的是DataFrame而非Series,直接赋值会导致数据类型异常,进而让S、Cl这类原子的计数无法正确提取;二是原正则没有考虑双字母原子(比如Cl、Br)的匹配逻辑,也没统一处理原子后无数字的情况(默认计数应为1)。

我给你写了个更通用且优雅的解决方案,既能覆盖单/双字母原子,还能自动处理无数字的原子计数:

import pandas as pd
import re

# 读取你的数据
myfile = "whatever.csv"
data = pd.read_csv(myfile, sep='|', header=0)

# 注意:双字母原子要放在单字母前面,避免正则先匹配到单字母(比如先匹配Cl,而不是先匹配C)
target_atoms = ['Cl', 'Br', 'Na', 'C', 'H', 'O', 'N', 'S']

# 正则模式:匹配双字母原子(如Cl)或单字母大写原子(如C),后面跟可选的数字
formula_pattern = re.compile(r'([A-Z][a-z]?)(\d*)')

def parse_formula(formula_str):
    # 捕获所有原子和对应的计数
    atom_matches = formula_pattern.findall(formula_str)
    # 构建计数字典:无数字的原子默认计数为1
    count_dict = {atom: int(num) if num else 1 for atom, num in atom_matches}
    # 返回目标原子的计数,不存在的原子返回0
    return pd.Series([count_dict.get(atom, 0) for atom in target_atoms], index=target_atoms)

# 批量处理所有分子式,生成原子计数列
atom_count_df = data['molecular_formula'].apply(parse_formula)
# 合并到原数据中
data = pd.concat([data, atom_count_df], axis=1)

# 可选:确保原子列为整数类型
data[target_atoms] = data[target_atoms].astype(int)

这个方案的优势:

  • 通用匹配:正则([A-Z][a-z]?)(\d*)能自动识别单字母和双字母原子,不用单独为每种原子写正则;
  • 自动处理无数字情况:如果原子后面没跟数字(比如分子式里的Cl),会自动设为1;
  • 高效简洁:用apply批量处理,比你之前的逐行loc操作高效得多,也更易维护;
  • 符合需求:原子不存在时默认返回0,完全满足你的要求。

用你给出的示例分子式C55H85N17O25S4测试,会得到你期望的输出:

molecular_formulaCHONClSBr
C55H85N17O25S455852517040

你之前的临时解决方案虽然能工作,但代码冗余且容易遗漏情况,这个方法能一次性解决所有问题~

内容的提问来源于stack exchange,提问作者thiR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:34:37