熊猫使用另一个系列作为查找值来查找行中关键字的位置



我正在尝试了解如何应用str.find()以在熊猫系列的字符串中找到关键字的索引位置。我想使用另一个系列,其中包含与 for 的输入值相同的数据帧中的字符串 forstr.find().

我尝试创建的输出是另一个系列,其中包含字符串中关键字位置的整数。 例如,对于第一行,我希望1,对于第二行,我希望2.

目标是使用query中关键字/关键字短语的完全匹配来查找"Title"字符串中的完全匹配项,并返回关键字在字符串中的位置Title。如果关键字/短语不存在,则显示 0。

预期产出

example_data = pd.DataFrame(([['key word1', 'key word1'], ['key word2', 'Find key word2, not key word1 or key word3 in title']]), columns=['query', 'Title'])

我的尝试

example_data = pd.DataFrame(([['key word1', 'key word1'], ['key word2', 'Find key word2, not keyword1 or keyword3 in title']]), columns=['query', 'Title'])
example_data['query_position'] = example_data['Title'].str.find(example_data['query'])

我得到的错误是:

类型错误:需要字符串对象,而不是系列

我不完全确定如何迭代该系列并将该系列中的字符串值输入str.find().

任何人的帮助都会很棒!

您还可以将series.str.splitexpand=True一起使用以转换为数据帧,然后使用df.eq检查数据帧是否与其他系列匹配:

example_data['position'] = (example_data['Title'].str.split(expand=True)
.eq(example_data['query']).idxmax(1)+1)
print(example_data)

query                       Title  position
0  keyword1  keyword1 keyword2 keyword3         1
1  keyword1  keyword2 keyword1 keyword3         2

如果可能缺少匹配项,您可以使用:

m = example_data['Title'].str.split(expand=True)
c = m.eq(example_data['query'])
example_data['position'] = np.where(c.any(1),c.idxmax(1)+1,np.nan)

使用.index,但也检查匹配,如果没有返回匹配-1

out = [b.split().index(a) + 1 
if a in b 
else -1 
for a, b in zip(example_data['query'], example_data['Title'])]
print (out)
[1, 2]
example_data['query_position'] = out

我找到的解决方案更pythonic,但有效。

str.find无济于事,因为它以字符数而不是单词的形式返回索引。

example_data['query_position'] = [len(t.split(q)[0].split(' ')) if len(t.split(q)) > 1 else 0 for t, q in zip(example_data['Title'].str.lower(), example_data['query'].str.lower())]

如果我理解正确,您正在尝试创建一个新列query_position,用于检查query中的字符串是否出现在Title中,然后给出位置。如果查询的字符串不存在于另一个字符串中,则str.find()方法返回 -1。您说过如果字符串不存在,您希望它返回 0,但如果您要搜索的字符串存在并且位于 0 索引处,则可能会导致混淆。

如果你真的想把它归零,这是我如何使用str.find()解决问题的方法:

# Quick custom function
def match_string(Title, query):
s = Title.find(query)
if s == -1:
return 0
else:
return s
# Use the .apply() function to create a new column using the custom function
example_data['query_position'] = example_data.apply(lambda x: match_string(x['Title'],
x['query']), axis=1)

如果要将 -1 保留原样,则可以使用以下方式将str.find()函数应用于数据帧:

example_data['query_position'] = example_data.apply(lambda x:str.find(x['Title'],
x['query']), axis=1)

我想你想要一个只枚举这样的行的列:

example_data['enum'] = range(example_data.count())

然后,如果您在标题字符串中找到查询字符串,只需像这样更新row_id:

example_data['query_position'] = example_data.apply(lambda x: x['enum'] if x['Title'].contains(x['query']) else 0)

让我知道这是否有帮助!

我不确定我是否理解这个问题。但是,添加将失败的行:

ample_data['query_position'] = pd.DataFrame(([['key word1', 'key word1'], ['key word2', 'Find key word2, not key word1 or key word3 in title'], ['kew word3', 'kew word1']]), columns=['query', 'Title'])

然后使用列表推导生成新列:

ample_data['query_position'] = [title.find(query) if title.find(query) > -1 else 0 for title, query in zip(ample_data['Title'], ample_data['query'])]

这给了:

query                                              Title  query_position
0  key word1                                          key word1               0
1  key word2  Find key word2, not key word1 or key word3 in ...               5
2  kew word3                                          kew word1               0

或将默认-1保留为"未找到":

ample_data['query_position'] = [title.find(query) for title, query in zip(ample_data['Title'], ample_data['query'])]

这给了:

query                                              Title  query_position
0  key word1                                          key word1               0
1  key word2  Find key word2, not key word1 or key word3 in ...               5
2  kew word3                                          kew word1              -1

最新更新