在Python中合并数组切片

时间:2014-09-26 13:23:19

标签: python bioinformatics

所以我有一个看起来像这样的字符串:

data="ABCABDABDABBCBABABDBCABBDBACBBCDB"

我正在随机拿出10个字符片:

start=int(random.random()*100)
end = start+10
slice = data[start:start+10]

但我现在要做的是计算“差距”的数量'或者'洞'根本没有切掉。

slices_indices = []
for i in xrange(0,100):
    start=int(random.random()*100)
    end= 10
    slice = data[start:end]
    ...
    slices_indices.append([start,end]) 

例如,运行几次后。我报道了这个数额:

ABCAB DABD ABBCBABABDB C ABBDBACBBCDB

但是留下了两个差距'切片。有没有' Pythonic'找到这些差距的方法?所以基本上我正在寻找count_gaps赋予切片索引的函数。

例如上面,

count_gaps(slices_indices)

会给我两个

提前致谢

3 个答案:

答案 0 :(得分:0)

有几个,虽然都涉及到一些混乱

您可以将删除的字符串与原始字符串进行比较,并计算出您未点击的字符。

这是一种非常迂回的方式,但如果你在字符串中有两次相同的10个字符,它将无法正常工作。例如1234123或其他什么。

更好的解决方案是存储您使用的i的值,然后退回数据字符串,将当前位置与您使用的i的值进行比较(加10)。如果不匹配,则完成工作。

例如(伪代码)

# Make an array the same length as the string
charsUsed = array(data.length)

# Do whatever
for i in xrange(0,100)
    someStuffYouWereDoingBefore()

    # Store our "used chars" in the array
    for(char = i; char < i+10; char++)
        if(char <= data.length) # Don't go out of bounds on the array!
            charsUsed[i] = true

然后看看哪些字符未被使用,只需遍历charsUsed数组并计算你想要计算的数量(连续间隙等)

编辑以回应更新的问题: 我仍然使用上面的方法来制作“使用了哪些字符”数组。然后你的count_gaps()函数只需要遍历数组来“找到”间隙

例如(伪......某事。这甚至不是模糊的Python。希望你能得到这个想法) 这个想法主要是看当前位置是否为假(即未使用),最后一个位置是否为真(使用),这意味着它是“新”缺口的开始。如果两者都是假的,我们就处于差距的中间,如果两者都是真的,我们就处于“使用过的”字符串的中间

function find_gaps(array charsUsed)
{
    # Count the gaps
    numGaps = 0
    # What did we look at last (to see if it's the start of a gap)
    # Assume it's true if you want to count "gaps" at the start of the string, assume it's false if you don't.
    lastPositionUsed = true

    for(i = 0; i < charsUsed.length; i++)
    {
        if(charsUsed[i] = false && lastPositionUsed = true)
        {
            numGaps++
        }
        lastPositionUsed = charsUsed[i]
    }

    return numGaps
}

另一种选择是再次单步执行charsUsed数组并将连续值“分组”到一个较小的距离,然后计算你想要的值...基本上相同的东西,但采用不同的方法。在这个例子中,我只是忽略我不想要的组和我所做的组的“休息”,只计算我们不想要的组和我们所做的组之间的界限。

答案 1 :(得分:0)

这是一个混乱的任务,但我认为套装是要走的路。我希望下面的代码是不言自明的,但如果有部分你不明白,请告诉我。

#! /usr/bin/env python

''' Count gaps.

    Find and count the sections in a sequence that weren't touched by random slicing
    From http://stackoverflow.com/questions/26060688/merging-arrays-slices-in-python
    Written by PM 2Ring 2014.09.27
'''

import random
from string import ascii_lowercase


def main():
    def rand_slice():
        start = random.randint(0, len(data) - slice_width) 
        return start, start + slice_width

    #The data to slice
    data = 5 * ascii_lowercase
    print 'Data:\n%s\nLength : %d\n' % (data, len(data))

    random.seed(42)

    #A set to capture slice ranges
    slices = set()    
    slice_width = 10    
    num_slices = 10
    print 'Extracting %d slices from data' % num_slices
    for i in xrange(num_slices):
        start, end = rand_slice()
        slices |= set(xrange(start, end))
        data_slice = data[start:end].upper()
        print '\n%2d, %2d : %s' % (start, end, data_slice)
        data = data[:start] + data_slice + data[end:]
        print data
        #print sorted(slices)

    print '\nSlices:\n%s\n' % sorted(slices)

    print '\nSearching for gaps missed by slicing'
    unsliced = sorted(tuple(set(xrange(len(data))) - slices))
    print 'Unsliced:\n%s\n' % (unsliced,)

    gaps = []    
    if unsliced:
        last = start = unsliced[0]
        for i in unsliced[1:]:
            if i > last + 1:
                t = (start, last + 1)
                gaps.append(t)
                print t
                start = i
            last = i
        t = (start, last + 1)
        gaps.append(t)
        print t

    print '\nGaps:\n%s\nCount: %d' % (gaps, len(gaps))


if __name__ == '__main__':
    main()

答案 2 :(得分:0)

我使用某种位图。例如,扩展您的代码:

data="ABCABDABDABBCBABABDBCABBDBACBBCDB"

slices_indices = [0]*len(data)
for i in xrange(0,100):
    start=int(random.random()*len(data))
    end=start + 10
    slice = data[start:end]
    slices_indices[start:end] = [1] * len(slice)

我在这里使用了list,但如果您的数据相当大,您可以使用任何其他适当的数据结构,可能更紧凑。

因此,我们用零初始化位图,并用选定的数据块标记。现在我们可以使用itertools中的内容,例如:

from itertools import groupby

groups = groupby(slices_indices)

groupby返回一个迭代器,其中每个元素都是一个元组(element, iterator)。要算出差距,你可以做一些简单的事情,比如:

gaps = len([x for x in groups if x[0] == 0])