两个布尔列/列表是不是匹配?两个不同大小的列的比较:一个列表的一部分是不是与另一个列表的一部分匹配? (Python)

Posted

技术标签:

【中文标题】两个布尔列/列表是不是匹配?两个不同大小的列的比较:一个列表的一部分是不是与另一个列表的一部分匹配? (Python)【英文标题】:Do two boolean colums/lists match? Comparison of two different sized colums: Does a part of one list match a part of the other? (python)两个布尔列/列表是否匹配?两个不同大小的列的比较:一个列表的一部分是否与另一个列表的一部分匹配? (Python) 【发布时间】:2022-01-16 09:20:40 【问题描述】:

我有不同长度的布尔值列表,我将其称为blists,我想将其与一段时间后的固定布尔值列表进行比较,我将其称为blist

目标是在blist 的列表(blists)中找到最长的匹配系列。

我想看看blists 的一部分甚至整个列表是否可以在blist 列表的某处找到。我会设置最少的匹配值,以免我的输出溢出。

例如(真 = T,假 = F,示例比现实生活中短):

List 1 of blists: (T,T,T,F,T,T,F,F,F,T)

blist: (F,F,T,T,F,F,F,F)

我想看看列表 1 (F,T,T,F,F,F) 的一部分是否等于列表 blist 的一部分。 因此,对于 (F,F,T,T,F,F,F,F) 的示例 blist,输出应该是,列表 1 的一部分可以在 blist 中找到。

所以输出例如:

blist与列表1相似((列表1中的起点)3,(blist中的起点)1,(长度)6,(匹配的部分列表):(F,T,T,F,F,F)

我尝试了.corr() 等、for-loops 和 if-conditions,但没有任何东西可以正常工作。

这个问题可能有一个简单的解决方案,但我想不通。

【问题讨论】:

【参考方案1】:

如果你想要一个实现来确定公共列表在每个列表的确切位置,这里有一个简单的“for循环”实现(为了便于阅读,我使用“0,1”而不是“True and False”。你可以轻松转换):

a = [0,1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,0,0]
b = [1,1,1,1,1,0,1,1,1,0,0,0,1,1]

list1_start = 0
list2_start = 0
common_list = []

for i in range(len(a)):
    for j in range(len(a)-i):
        for i2 in range(len(b)):
            for j2 in range(len(b)-i2):
                if a[i:i+j] == b[i2:i2+j2]:
                    if len(common_list)<len(a[i:i+j]):
                        common_list = a[i:i+j]
                        list1_start = i+1
                        list2_start = i2+1
                    
print("list1 start: ", list1_start)
print("list2 start: ", list2_start)
print("common_list: ",common_list)

答案:

list1 start:  10
list2 start:  3
common_list:  [1, 1, 1, 0, 1, 1, 1, 0]

【讨论】:

【参考方案2】:

我建议使用KMP algorithm 之类的东西来匹配整个列表中的子集列表。它将利用 O(n) 复杂度。完全实现使用最坏的 O(n^3),但最有可能使用 O(n^2)。解决方案可能如下所示:

longest_match = []

for i in range(len(blists)):
  if(i+len(longest_match) >= len(blists):
    break
  for j in range(i+len(longest_match)+1, len(blists)):
    if(KMPSearch(blists[i,j], blist)):
      longest_match = blists[i,j]
    else:
      break

循环遍历 blists 中的每个位置并检查从 i 开始的子集列表,并超过已找到的最长匹配的长度。

【讨论】:

【参考方案3】:

一种方法是将列表加入字符串并使用“in”和“find”字符串方法和循环:

l1 = ['T','T','T','F','T','T','F','F','F','T']
blist = ['F','F','T','T','F','F','F','F']

w1, bw = ''.join(l1), ''.join(blist)

all_options = sum([[w1[i:ii] for i in range(len(w1))] for ii in range(len(w1))], [])
all_valid_options = [x for x in all_options if (len(x)>1 and x in bw)]
longest_option = sorted(all_valid_options, key=len)[-1]

w1_start = w1.find(longest_option)
w1_end = w1_start + len(longest_option)
bw_start = bw.find(longest_option)
bw_end = bw_start + len(longest_option)
print(longest_option, len(longest_option), (w1_start, w1_end), (bw_start, bw_end))

FTTFFF 6 (3, 9) (1, 7)

【讨论】:

以上是关于两个布尔列/列表是不是匹配?两个不同大小的列的比较:一个列表的一部分是不是与另一个列表的一部分匹配? (Python)的主要内容,如果未能解决你的问题,请参考以下文章

两个文件中的AWK列匹配,打印不同的列

比较两列的熊猫数据框,如果不同,则使用正确的列之一

Scala Spark,比较两个 DataFrame 并选择另一列的值

PyQt:如何为单个标题设置不同的标题大小?

如何匹配两个不同表中的列并将选定的列输出到 MySQL 中的第三个表?

当它们具有不同的列集时,按行组合两个数据帧(rbind)