python - 如何通过与另一列字符串进行比较来对具有真值和假值的字符串列进行分类

标签 python chemistry

所以我有一列被列为“化合物”的字符串

组成(列标题)

ZrMo3

Gd(CuS)3

Ba2DyInTe5

我还有另一列,其中包含元素周期表中的字符串金属元素,我将该列称为“金属”

元素(列标题)

目标是检查“化合物”中的每个字符串与“金属”中列出的每个字符串,如果存在任何来自金属的字符串,则将其分类为 true。我有什么想法可以编码吗?

示例:(如果“金属”包含 Zr、Ag 和 Te)

ZrMo3 正确

Gd(CuS)3 假

Ba2DyInTe5 正确

我最近尝试使用下面的代码,但最终得到的都是 false

asd = subset['composition'].isin(metals['Elements'])
    
print(asd)

也尝试了这段代码,结果也都是错误的

subset['Boolean'] = subset.apply(lambda x: True if any(word in x.composition for word in metals) else False, axis=1)

最佳答案

假设您使用的是 pandas,您可以使用 list comprehension在 lambda 内部,因为您本质上需要迭代 elements 列表

中的所有元素
import pandas as pd

elements = ['Li', 'Be', 'Na', 'Te']
compounds = ['ZrMo3', 'Gd(CuS)3', 'Ba2DyInTe5']

df = pd.DataFrame(compounds, columns=['compounds'])
print(df)

输出

  compounds
0       ZrMo3
1    Gd(CuS)3
2  Ba2DyInTe5

df['boolean'] = df.compounds.apply(lambda x: any([True if el in x else False for el in elements]))
print(df)

输出

    compounds  boolean
0       ZrMo3    False
1    Gd(CuS)3    False
2  Ba2DyInTe5     True

如果您不使用 pandas,您可以使用 map 函数将 lambda 函数应用于列表

out = list(
    map(
        lambda x: any([True if el in x else False for el in elements]), compounds)
)
print(out)

输出

[False, False, True]

这里将是一个更复杂的版本,它还解决了 @Ezon 提到的基于正则表达式匹配模块re的潜在错误。因为这种方法本质上不仅是在元素上循环以与单个复合字符串进行比较,而且是在复合的每个组成部分上循环,因此我创建了两个辅助函数以使其更具可读性。

import re
import pandas as pd


def split_compounds(c):
    
    # remove all non-alphabet elements
    c_split = re.sub(r"[^a-zA-Z]", "", c)
    # split string at capital letters
    c_split = '-'.join(re.findall('[A-Z][^A-Z]*', c_split))
    return c_split

def compare_compound(compound, element):
    
    # split compound into list
    compound_list = compound.split('-')
    
    return any([element == c for c in compound_list])
    
    
# build sample data
compounds = ['SiO2', 'Ba2DyInTe5', 'ZrMo3', 'Gd(CuS)3']
elements = ['Li', 'Be', 'Na', 'Te', 'S']
df = pd.DataFrame(compounds, columns=['compounds'])

# split compounds into elements
df['compounds_elements'] = [split_compounds(x) for x in compounds]

print(df)

输出

    compounds compounds_elements
0        SiO2               Si-O
1  Ba2DyInTe5        Ba-Dy-In-Te
2       ZrMo3              Zr-Mo
3    Gd(CuS)3            Gd-Cu-S


# check if any item from 'elements' is in the compounds
df['boolean'] = df.compounds_elements.apply(
    lambda x: any([True if compare_compound(x, el) else False for el in elements])
)

print(df)

输出

    compounds compounds_elements  boolean
0        SiO2               Si-O    False
1  Ba2DyInTe5        Ba-Dy-In-Te     True
2       ZrMo3              Zr-Mo    False
3    Gd(CuS)3            Gd-Cu-S     True

关于python - 如何通过与另一列字符串进行比较来对具有真值和假值的字符串列进行分类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74527231/

相关文章:

python - 如何使用 MDAnalysis 分析一组原子的principal_axes 和 moment_of_inertia?

java - 解析化学式

python - 提取组

python - 在调查中补偿 "variance"

python - 如何搭建深度学习图像处理服务器

python - 在 Jupyter Notebook Pandas 的 For 循环中打印视觉上令人愉悦的数据帧

python - 请求 http 库 : include X-Request-ID

gnuplot - 如何正确地将透视图添加到代表分子的 Gnuplot 3D 连接点云?

python - 在 Python 中计算有效数字?

java - 将化学式转换为其 iupac 名称