高效且最快速的方式来完成文件整个长度的滑动窗口

时间:2016-10-14 12:50:26

标签: python loops sliding-window

我有一个制表符分隔文件,其中包含大约2207行,其中包含4列浮点数或整数类型,如下所示: -

Id    pos    value1    value2
01    1123   0.76483   0.9001
02    1124   0.20      0.9800

要比较的另一个文件包含大约27041行和4列: -

name    Id    pos1    pos2
s13e    01    234     800
zz12    01    800     866

现在,我的目标是找到所有可能连续的3行或更高的行

  1. 第一个文件(Id)第一列的内容等于第二个文件(Id)的第二列。
  2. 第一个文件(pos)第二列的内容介于第二个文件的第3列和第4列之间。
  3. 我的方法是做以下事情:

    1. 循环浏览一个长度为3的滑动窗口到第一个文件的整个行数(这就是我的外循环)
    2. 第二个循环是迭代并获取某个特定长度的滑动窗口的每个元素,例如3然后
    3. 检查该元素是否满足上述条件,如果满足则打破循环以获取第一个文件的下一个元素
    4. 否则继续搜索第二个文件以找到目标
    5. 对于第一个文件的300行长度,检查第二个文件的整个滑动窗口大约需要5分钟。但是,我正在寻找一种更快,更有效的方法。

      满意结果的一个例子如下,假设我们已经执行了长度为3的窗口滑动:

      从文件1:

      idW = (01,01,01)
      posW = (127, 192,199)
      val1W = (.9,.01,.23)
      val2W = (.2,.03,.43)
      

      从文件2:

      name    Id    pos1    pos2
      s13e    01    120     200
      

      为了满足,必须满足以下条件: 第一个文件的posW介于pos1和pos2的值之间,来自file2:

      连续行3行(true)

      file1的id等于file2 (true)

      posW介于pos1和pos2(true)的值之间

      结果是满足的,因为上述所有条件都是真的并且符合

      代码片段如下:

      # borrowed from one answer from stack overflow 
      def sliding_window (s, n):
       it = iter(seq)
       result = tuple(islice(it, n))
       if len(result) == n:
          yield result
       for elem in it:
          result = result[1:] + (elem,)
          yield result
      
      Ids, pos, val1, val2 = zip(*Data)
      # len_Data is the entire length of the file 
      for windwCounts in range(3,len_Data):
          file2count = 0
          swindow_id = sliding_window(Ids, windwCounts)
          swindow_pos = sliding_window(pos, windwCounts)
          swindow_val1 = sliding_window(val1, windwCounts)
          swindow_val2 = sliding_window(val2, windwCounts)
          slidingWindws = zip(swindow_id, swindow_pos,
                              swindow_val1, swindow_val2)
          for idW, posW, val1W, val2W in slidingWindws:
           while (file2count <= len_file2):
                  name,id2,pos1,pos2 = file2[file2count]
                  # No point of moving down if the pos of file1 is less than pos2 of file2
                  if any(int(ps) < pos2 for ps in posW):
                          break
                  # All conditions must be met:-
                  ids_cond = all(a_id == id2 for a_id in idW)
                  within_data = all(pos1 <= int(ps) <= pos2
                                             for ps in posW)
                  if ids_cond and within_data:
      
                        print "satisfy"
                        break 
      
                  else:
                        print "not satisfy"
                  genesCounts += 1
      

      提前多多感谢,真正感谢帮助!!!

0 个答案:

没有答案