我正在尝试了解如何应用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.split
与expand=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