一个关于布尔比较的问题:如何将子字符串列表与字符串列表进行比较?

3

我做了一些研究,但没有找到下面问题的答案。

如何在字符串列表中比较子字符串列表的布尔值?

下面是代码:

string = {'strings_1': ['AEAB', 'AC', 'AI'], 
             'strings_2':['BB', 'BA', 'AG'], 
             'strings_3': ['AABD', 'DD', 'PP'], 
             'strings_4': ['AV', 'AB', 'BV']}

df_string = pd.DataFrame(data = string)

substring_list = ['AA', 'AE']

for row in df_string.itertuples(index = False):
    combine_row_str = [row[0], row[1], row[2]]

    #below is the main operation
    print(all(substring in row_str for substring in substring_list for row_str in combine_row_str))

我得到的输出是:
False
False
False

我需要的输出是:
True
False
False
2个回答

3

以下是使用pd.DataFrame.sum和列表推导的一种方法:

df = pd.DataFrame(data=string)

lst = ['AA', 'AE']

df['test'] = [all(val in i for val in lst) for i in df.sum(axis=1)]

print(df)

  strings_1 strings_2 strings_3 strings_4   test
0      AEAB        BB      AABD        AV   True
1        AC        BA        DD        AB  False
2        AI        AG        PP        BV  False

2
由于您正在使用pandas,因此可以调用逐行应用(apply)和带有正则表达式的str.contains函数来查找字符串是否匹配。第一步是查找任何一个值是否与substring_list中的字符串匹配:
df_string.apply(lambda x: x.str.contains('|'.join(substring_list)), axis=1)

这个返回:
   strings_1  strings_2  strings_3  strings_4
0       True      False       True      False
1      False      False      False      False
2      False      False      False      False

现在,不清楚的是,您想在行内同时出现两个子字符串时返回true,还是只要其中任何一个。如果只要其中任何一个,您可以在contains()方法后面添加any():
df_string.apply(lambda x: x.str.contains('|'.join(substring_list)).any(), axis=1)

这句话的意思是“这将返回:”。
0     True
1    False
2    False
dtype: bool

对于第二种情况,jpp 提供了一行解决方案,将行元素连接成一个字符串,但请注意,当您有两个相邻的元素时,比如 "BBA" 和 "ABB",并尝试匹配 "AA" 时,它将无法正常工作。连接后的字符串 "BBAABB" 仍将匹配 "AA",这是错误的。我想提出一种使用 apply 和额外函数的解决方案,以使代码更易读:
def areAllPresent(vals, patterns):
  result = []
  for pat in patterns:
    result.append(any([pat in val for val in vals]))
  return all(result)

df_string.apply(lambda x: areAllPresent(x.values, substring_list), axis=1)

由于您的样本数据框,它仍将返回相同的结果,但对于需要匹配两者的情况,它是有效的:
0     True
1    False
2    False
dtype: bool

1
嘿,感谢您的回答。如果我想让每个位置都包含“AA”和“AE”,我该怎么办?也就是说,布尔检查行0和列0是否包含'AA'和'AE'子字符串。布尔检查行0和列1是否同时包含'AA'和'AE',以此类推... - learner
1
我尝试过这样做,但是不起作用: df_string.apply(lambda x: x.str.contains((?=substring_list), axis=1) - learner
1
谢谢。为什么不是 (?=.AA.)(?=.AE.)? - learner
(?=.AA.)(?=.AE.) 做的是同样的事情,尾随的 .* 是多余的,因为 ?= 是一个正向前瞻运算符。这意味着它将匹配表达式组,但不会捕获它,下一个组将与初始匹配字符串匹配。本质上,您正在在正则表达式中再现 AND 运算符。请看这里:正则表达式:是否有 AND 运算符? - user59271
谢谢。我之前看过那篇帖子。抱歉我落后了一步:为什么我需要首先使用 .*?代码不应该返回布尔值 true 表明 'AA' 是 'AABD' 的子字符串吗? - learner
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接