在另一个numpy数组中查找数组字符串序列

时间:2019-07-02 19:53:44

标签: python arrays numpy sequence

我对遍历数组有疑问。我需要找到一些存储在数组中的字符串序列,例如,它可能看起来像这样 array1:

['818181' '747473' '747474' '636363' '767676' '737373' '727373' '373838'
 '697070' '686869' '115115115' '737474' '757575' '777777' '818181' '747473'
 '747474' '636363' '767676' '737373' '727373' '757575' '696969']

这是一个带有字符串的numpy数组。 Dtype显示它是S9。 然后我有另一个具有相同结构但更大的主数组。我正在寻找最有效的方法来查找array1在主数组中开始的位置,因此就像我在numpy数组中查找指定的模式一样。这些值重复出现,我需要找到完全相同的值。我一直在寻找最佳解决方案,但找不到任何有帮助的方法。主数组很大,我需要在1秒内获得array1位置。不幸的是,我发现了一些有关在数组中查找序列的示例脚本,但这对我没有帮助。通常,他们在小型数组中找到一些整数值。我需要一些建议。

我尝试使用enumerate()中的e遍历整个数组 因此,一个元素看起来像这样-'818181'。然后,我计算是否行中的23个元素(在此示例中)相同。但是当第5个元素错误时,我就必须走到第1个元素的位置才能获得100%成功(因为模式可以互相影响),而且速度非常慢。

主数组类似于array1,但是1000x并具有更多值

2 个答案:

答案 0 :(得分:0)

您可以遍历array1中的每个值,并使用np.where()获取主数组中值的索引。将索引添加到列表中,然后对列表进行排序。然后找到与数组1的长度匹配的索引的连续长度。

例如:

def consecutive(data, stepsize=1):
    return np.split(data, np.where(np.diff(data) != stepsize)[0]+1)

index_list = []
for val in array1:
    index_list.extend(list(np.where(main_array == val)))
index_list.sort()

for sequence in consecutive(index_list):
    if len(sequence) == len(array1):
        print(sequence)

how to find the groups of consecutive elements from an array in numpy?到@unutbu的连续功能。

答案 1 :(得分:-1)

一点也不;再看一遍。当您到达第5个元素时,您已经知道第2、3、4个元素不是第一个元素,因此您只需移至不匹配元素即可。

这是语法中的一个众所周知的问题,可以用有限状态机来处理。

首先不用担心字符串的内容;重要的是要找到一系列符号。每个“数字”字符串都是不同的符号。为了方便起见,让我们进行如下映射:

'818181' => a
'747473' => b
'747474' => c
etc.

因此数组可以简化为以下形式:

 '818181' '747473' '747474' '636363' '767676' '737373' '727373' '373838'
  a        b        c        d        e        f        g        h
 '697070' '686869' '115115115' '737474' '757575' '777777' '818181' '747473'
  i        j        k           l        m        n        a        b
 '747474' '636363' '767676' '737373' '727373' '757575' '696969']
  c        d        e        f        g        m        o

或者,作为单行序列:

  abcdefghijklmnabcdefgmo

在您提到的情况下,b不匹配,我们不必备份到输入的b位并重新开始;我们已经确定bcd匹配,并且它们不是 a,因此我们不进行备份:我们只是再次比较a到不匹配的商品。

碰巧,我们从不必须备份。最糟糕的是,我们将继续检查匹配失败的位置,而不是目标字符串的开头。我们必须处理一个棘手的情况:中间字符串匹配。

考虑当我们在目标序列结尾附近的第二个m处存在不匹配时会发生什么。在这种情况下,我们知道我们刚刚匹配了abcdefg,但是当前符号不是 m ...但是如果可能h。为了避免备份,我们利用部分匹配的优势,并使用h重新开始检查。

要处理此算法,您需要对目标字符串进行一些预处理。制作第二个数组,保存目标字符串中每个位置的重启索引。您可以通过简单地检查它与自身正面的偏离位置来完成此操作。对于您的示例来说,很简单:o是唯一的主字符串和移位字符串匹配多个字符,但在此位置不同的地方。

  abcdefghijklmnabcdefgmo
  11111111111111111111181

这会让你动起来吗?