我见过关于这个话题的问题,但大多数都与我的相反。我有一个字符串列表(数据框的列)和一个子字符串列表。我想将每个字符串与子字符串列表进行比较如果它包含一个子字符串,则返回该子字符串,否则打印“不匹配”。
subs = [cat, dog, mouse]
df
Name Number SubMatch
dogfood 1 dog
catfood 3 cat
dogfood 2 dog
mousehouse 1 mouse
birdseed 1 no match
我当前的输出看起来像这样:
Name Number SubMatch
dogfood 1 dog
catfood 3 dog
dogfood 2 dog
mousehouse 1 dog
birdseed 1 dog
我怀疑我的代码只是返回系列中的第一件事,如何将其更改为系列中的正确内容?这是功能:
def matchy(col, subs):
for name in col:
for s in subs:
if any(s in name for s in subs):
return s
else:
return 'No Match'
答案 0 :(得分:4)
str.extract
:完成此操作
p = '({})'.format('|'.join(subs))
df['SubMatch'] = df.Name.str.extract(p, expand=False).fillna('no match')
df
Name Number SubMatch
0 dogfood 1 dog
1 catfood 3 cat
2 dogfood 2 dog
3 mousehouse 1 mouse
4 birdseed 1 no match
答案 1 :(得分:1)
这个怎么样:
def matchy(col, subs):
for name in col:
try:
return next(x for x in subs if x in name)
except StopIteration:
return 'No Match'
您的代码存在的问题是您正在检查与any
的匹配,但首先返回迭代的第一项(dog
)。
编辑赞誉@Coldspeed
def matchy(col, subs):
for name in col:
return next(x for x in subs if x in name, 'No match')
答案 2 :(得分:0)
我认为你已经完成了使用嵌套循环复杂化的事情,然后是any
测试。这会更好吗:
def matchy(col, subs):
for name in col:
for s in subs:
if s in name:
return s
else:
return 'No Match'
答案 3 :(得分:0)
除非缺少对其进行说明的代码,否则您的代码似乎会返回第一次比较的结果,并且实际上不会查看col
列表中的任何其他项。如果您更愿意坚持使用嵌套循环,我建议您修改代码:
def matchy(col, subs):
subMatch = []
for name in col:
subMatch.append('No Match')
for s in subs:
if s in name:
subMatch[-1] = s
break
return subMatch
这假定col
是包含列信息(dogfood,mousehouse等)的字符串列表,subs
是包含您要搜索的子字符串的字符串列表。 subMatch
是matchy
返回的字符串列表,其中包含col
中每个项目的搜索结果。
对于我们检查的col
中的每个值,我们将'No Match'
字符串附加到subMatch,基本上假设我们找不到匹配项。然后我们遍历subs
,检查s
中是否包含子串name
。如果匹配,则subMatch[-1] = s
会替换我们附加匹配子字符串的最新'No Match'
,然后我们会转到col
中的下一个项目,因为我们不需要搜索更多值。请注意,subMatch[-1] = s
可以替换为其他方法,例如执行subMatch.pop()
后跟subMatch.append(s)
,但此时我认为这更偏向个人。检查col
中的所有元素后,系统会返回subMatch
,然后您可以按照自己的喜好处理它。