Python 在标记一个列之后,在一个特定的单词之前和之后获得两个单词

Python 在标记一个列之后,在一个特定的单词之前和之后获得两个单词,python,pandas,dataframe,Python,Pandas,Dataframe,我只是使用nltk.word\u tokenize标记了数据帧中的一列。 这个专栏现在看起来像 df.tokenized > 0 [apple, hi, dog, boy, why...] > 1 [table, hey, girl, cat, dog, 2, 3... 对于每一行,我需要在单词“dog”前两个单词,在单词“dog”后两个单词。我想把它全部放在同一数据帧中的另一列中。我期望的输出类似于: df.tokenized_part2 > 0 [

我只是使用nltk.word\u tokenize标记了数据帧中的一列。 这个专栏现在看起来像

df.tokenized
> 0     [apple, hi, dog, boy, why...]
> 1     [table, hey, girl, cat, dog, 2, 3...
对于每一行,我需要在单词“dog”前两个单词,在单词“dog”后两个单词。我想把它全部放在同一数据帧中的另一列中。我期望的输出类似于:

df.tokenized_part2
> 0     [apple, hi, dog, boy, why]
> 1     [girl, cat, dog, 2, 3]
因此,我需要创建这个标记为第2部分的列

如果您需要此信息: 标记化对象


有人知道怎么做吗?

一种方法是将apply与lambda-like一起使用

lambda x: [i for ix,i in enumerate(x) if ix in range([idx for idx,it in x if it=='dog'][0]-2,[idx for idx,it in x if it=='dog'][0]+2)]
但它的计算成本很高,容易出错,而且可能不必要地复杂。

您可以使用
apply()
在列中的每个单元格上运行函数,此函数可以获取
狗在列表中的位置,并返回
[pos-2:pos+3]

import pandas as pd

df = pd.DataFrame({
"tokenized": [
    ['apple', 'hi', 'dog', 'boy', 'why', 'other'],
    ['table', 'hey', 'girl', 'cat', 'dog', '2', '3'],
    ['A', 'B', 'C'],
]
})

def process(words):
    #print(words)
    if 'dog' in words:
        pos = words.index('dog')
        return words[pos-2:pos+3]
    else:
        #return words
        return []

df["tokenized_2"] = df["tokenized"].apply(process)

print(df)
结果:

                            tokenized                 tokenized_2
0   [apple, hi, dog, boy, why, other]  [apple, hi, dog, boy, why]
1  [table, hey, girl, cat, dog, 2, 3]      [girl, cat, dog, 2, 3]
2                           [A, B, C]                          []
                tokenized_dog             tokenized_cat
0  [apple, hi, dog, boy, why]                        []
1      [girl, cat, dog, 2, 3]  [hey, girl, cat, dog, 2]
2                          []                        []

编辑:

为了使其更通用,可以将
dog
(或其他单词)作为参数,然后您可以使用
lambda
(或
部分
)运行它

结果:

                            tokenized                 tokenized_2
0   [apple, hi, dog, boy, why, other]  [apple, hi, dog, boy, why]
1  [table, hey, girl, cat, dog, 2, 3]      [girl, cat, dog, 2, 3]
2                           [A, B, C]                          []
                tokenized_dog             tokenized_cat
0  [apple, hi, dog, boy, why]                        []
1      [girl, cat, dog, 2, 3]  [hey, girl, cat, dog, 2]
2                          []                        []

这是完全不可读的,或者understandable@gold_cy它实际上是另一个答案的
过程
,作为lambda中的嵌套列表理解。或者更确切地说,因为它们是在我之后应答的,所以它们的函数是我的嵌套列表,以不必要的字符数量展开。如果有人需要向你解释,理解中的占位符(如循环)和lambda表达式(比如函数)不需要有意义的是可以理解的,那么你应该考虑这个问题的根源所在。他们想要工作代码。代码是有效的。牺牲代码行以使其可读始终被认为是正确的方法。额外的代码行并不意味着额外的处理。在Python这样的语言中,可读性是最重要的,它的优点是什么。我认为这是一个惊人的类库组合,动态类型和在代码中以难以置信的效率解决问题的能力,而不必为简单的问题输入大量的代码。顺便说一句,我现在将选择以编程方式而不是自然语言的方式理解您的第一条注释。谢谢你说我的代码是可以理解的@gold\u cy。也许你应该迭代每一行,搜索每一行的位置,然后得到
[pos-2:pos+2]
如果列表上没有狗怎么办?太好了!为了使其更具通用性:列表中的项目的列表单词=['cat'、'dog'、'bird']。\u单词:df['col'+''.+str(项目)]=df[“标记化”]。应用(lambda单词:过程(单词,项目))