从一个DataFrame列中提取单词,赋值给另一列

2 投票
3 回答
55 浏览
提问于 2025-04-13 14:22

我有一个数据表,里面有两列:害虫(Pests)和字段评论(FieldComment)。如果害虫这一列的值是“None”,那么我想在字段评论这一列中查找特定的词,并把害虫这一列的内容替换成找到的词。如果在字段评论中没有找到这些词,害虫这一列就保持为“None”。

举个例子:

pests_list = ['Spiders', 'Rodents', 'Ants', 'Honey Bees']
害虫 字段评论
蜘蛛 进行了服务。
None 为报告的啮齿动物进行了服务。

上面的内容理想情况下应该变成这样:

害虫 字段评论
蜘蛛 进行了服务。
啮齿动物 为报告的啮齿动物进行了服务。

这是我目前尝试过的,但还没完全搞定:

for w in df['FieldComment'].str.split():
    for p in pests_list:
        if w.str.lower() == p.str.lower():
            df['Pests'] = p

我还尝试过:

df.loc[df['Pests'] == 'None', "Pests"] =  *[pest for pest in pest_list if pest in df['FieldComment']]

最后:

df.loc[df['Pests'] == 'None', "Pests"] = df.loc[df['Pests'] == 'None', "Pests"].apply(lambda x: pest for pest in pest_list if pest in df['FieldComment'] else 'None')

3 个回答

0

我会根据害虫列表创建一个正则表达式,然后像这样使用 str.extract

import re
pests_re = rf"({'|'.join(pests_list)})"
df["Pests"] = df.Pests.fillna(
    df.FieldComment
    .str.extract(
        pests_re, 
        flags=re.I, # case insensitive 
        expand=False # output as Series
    )
)
0

一种可能的解决办法是遍历一下所有在 pests_list 里的值,然后在字符串中寻找第一次出现的位置。

pests_list = ["Spiders", "Rodents", "Ants", "Honey Bees"]

mask = df["Pests"].isna()

df.loc[mask, "Pests"] = [
    next((p for p in pests_list if p.lower() in c), None)
    for c in df.loc[mask, "FieldComment"].str.lower()
]
print(df)

输出结果:

     Pests                             FieldComment
0  Spiders                       Performed service.
1  Rodents  Performed service for reported rodents.
2     None              Nothing will be found here.
3
  1. 把害虫的 list 转换成一个 set
  2. FieldComment 中的词语创建一个 set
  3. 找出两个 set 的交集,并在 Pests 列为空的地方填入这些交集的内容。
pests_set = set([p.lower() for p in pests_list])

df.loc[df["Pests"].isna(), "Pests"] = df["FieldComment"].apply(
    lambda x: ", ".join(
        set(x.strip(".").lower().split()).intersection(pests_set)
    ).capitalize()
)
     Pests                             FieldComment
0  Spiders                       Performed service.
1  Rodents  Performed service for reported rodents.

这个方法会把 FieldComment 列中如果有多个害虫名字的话,用 , 连接起来。比如对于这个数据框:

     Pests                                FieldComment
0  Spiders                          Performed service.
1     None  Performed service for rodents and spiders.

结果会是:

              Pests                                FieldComment
0           Spiders                          Performed service.
1  Spiders, rodents  Performed service for rodents and spiders.

需要注意的是,如果数据框中有一个字符串 'None',而不是 Python 的 None 关键字,你需要稍微修改一下上面的代码,把 df["Pests"].isna() 改成 df["Pests"] == 'None'

撰写回答