首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提取具有对齐数据差异的列

提取具有对齐数据差异的列
EN

Stack Overflow用户
提问于 2014-08-09 14:13:08
回答 2查看 38关注 0票数 0

我有一些对齐的数据(一些与生物信息有关的数据)如下:

代码语言:javascript
复制
reference_string = 'yearning'
string2 = 'learning'
string3 = 'aligning'

我只需要提取显示与参考数据不同的列。输出只应显示列的位置信息,其中包含与引用字符串和相应引用项有关的差异。

代码语言:javascript
复制
       1 2 3 4
       y e a r
       l
       a l i g

我的当前代码做的大多数事情都还行,只是它也报告了没有区别的列。

代码语言:javascript
复制
string1 = 'yearning'
string2 = 'learning'
string3 = 'aligning'

string_list = [string1, string2]

reference = reference_string
diffs_top, diffs = [], []
all_diffs = set()

for s in string_list:
    diffs = []
    for i, c in enumerate(s):
        if s[i] != reference[i]:
            diffs.append(i)
            all_diffs.add(i)
    diffs_top.append(diffs)

for d in all_diffs:
    print str(int(d+1)),
print

for c in reference:
    print str(c),
print

for i, s in enumerate(string_list):
    for j, c in enumerate(s):
        if j in diffs_top[i]:
            print str(c),
        else:
            print str(' '),
    print

这一守则将规定:

代码语言:javascript
复制
1 2 3 4
y e a r n i n g

l              
a l i g  

任何帮助都很感激。

编辑:--我已经选择了一些实际数据,以使问题尽可能清晰,并试图解决这个问题:

代码语言:javascript
复制
reference_string = 'MAHEWGPQRLAGGQPQAS'
string1 = 'MAQQWSLQRLAGRHPQDS'
string2 = 'MAQRWGAHRLTGGQLQDT'
string3 = 'MAQRWGPHALSGVQAQDA'

string_list = [string1, string2, string3]

reference = reference_string
diffs_top, diffs = [], []
all_diffs = set()

for s in string_list:
    diffs = []
    for i, c in enumerate(s):
        if s[i] != reference[i]:
            diffs.append(i)
            all_diffs.add(i)
    diffs_top.append(diffs)
#print diffs_top
#print all_diffs

for d in all_diffs:
    print str(int(d+1)), # retains natural positions of the reference residues
print

for d in all_diffs:
    for i, c in enumerate(reference):
        if i == d:
            print c,
print

打印出的输出将显示与其他非引用字符串和相应的参考字母有任何差异的位置。

代码语言:javascript
复制
3 4 6 7 8 9 11 13 14 15 17 18
H E G P Q R A G Q P A S

然后,下一步是编写一个代码,通过打印出与引用的差异(在那个位置)来处理非引用字符串。如果没有区别,它将留下空白(‘')。

手动执行此操作,输出如下:

代码语言:javascript
复制
3 4 6 7 8 9 11 13 14 15 17 18
H E G P Q R  A  G  Q  P  A  S
Q Q S L         R  H     D  
Q R   A H    T        L  D  T
Q R     H A  S  V     A  D  A

我的整个代码都是为了达到上述解决方案而编写的,至少可以说是混乱的:

代码语言:javascript
复制
reference_string = 'MAHEWGPQRLAGGQPQAS'
string1 = 'MAQQWSLQRLAGRHPQDS'
string2 = 'MAQRWGAHRLTGGQLQDT'
string3 = 'MAQRWGPHALSGVQAQDA'

string_list = [string1, string2, string3]

reference = reference_string
diffs_top, diffs = [], []
all_diffs = set()

for s in string_list:
    diffs = []
    for i, c in enumerate(s):
        if s[i] != reference[i]:
            diffs.append(i)
            all_diffs.add(i)
    diffs_top.append(diffs)
#print diffs_top
#print all_diffs

for d in all_diffs:
    print str(int(d+1)),
print

for d in all_diffs:
    for i, c in enumerate(reference):
        if i == d:
            print c,
print

# this is my attempt to look into non-reference strings
# to check for the difference with the reference, and print an output.
for d in all_diffs:
    for i, s in enumerate(string_list):
        for j, c in enumerate(s):
            if j == d:
                print c,
            else:
                print str(' '),
print
EN

回答 2

Stack Overflow用户

发布于 2014-08-09 15:18:37

您的代码工作非常好(按照您的逻辑)。

所发生的情况是,在打印输出时,当您看到引用字符串时,Python会在diffs_top列表中查找相应的条目,因为在diff_top中存储时,您没有存储引用字符串的条目,Python只是打印引用字符串的空格。

代码语言:javascript
复制
1 2 3 4
y e a r n i n g #prints the reference string, because you've coded in that way
                #prints blank as string_list[0] and reference string are the same
l
a l i g

这里的问题是如何准确地定义引用字符串的差异。

此外,我还发现了代码实现中的一些基本缺陷。如果您试图通过将string_list[1]设置为引用字符串来运行您的代码,您将得到如下输出:

代码语言:javascript
复制
1 2 3 4
l e a r n i n g
y

a l i g

这就是你需要的吗?请花一些时间正确定义所有情况下的差异,然后尝试实现您的代码。

编辑:

根据您更新的要求,将代码中的最后一个块替换为:

代码语言:javascript
复制
for i, s in enumerate(string_list):
    for d in all_diffs:
        if d in diffs_top[i]:
            print s[d],
        else:
            print ' ',
    print

干杯!

票数 2
EN

Stack Overflow用户

发布于 2014-08-09 14:26:19

我认为你的逻辑中有一个普遍的问题。如果您只需要提取显示与引用数据不同的列,并且string1是引用,则输出应该是:

代码语言:javascript
复制
1 2 3 4

l
a l i g

因此,'yearning'不应该显示任何字符,因为它与string1没有区别。

如果删除或在注释中添加以下行,您将得到我期望的正确答案:

代码语言:javascript
复制
#for c in reference:
#    print str(c),
#print

如果这个解决方案不是您真正想要的,请考虑检查您的逻辑。

更新

下面是解决您的任务的一个较短的解决方案:

代码语言:javascript
复制
from itertools import compress, izip_longest

def delta(reference, string):
    return [ '' if a == b else b for a, b in izip_longest(reference, string)]    

ref_string = 'MAHEWGPQRLAGGQPQAS'
strings = ['MAQQWSLQRLAGRHPQDS',
           'MAQRWGAHRLTGGQLQDT',
           'MAQRWGPHALSGVQAQDA']

delta_strings = [delta(ref_string, string) for string in strings]
selectors = [1 if any(tup) else 0 for tup in izip_longest(*delta_strings)]
indices = [str(i+1) for i in range(len(selectors))]

output_data = [indices, ref_string] + delta_strings

for line in output_data:
    print ''.join(x.rjust(3) for x in compress(line, selectors))

解释:

  • 我定义了一个函数delta(reference, string),它返回字符串和引用字符串之间的增量。例如:delta("ABFF", "AECF")返回列表['', E, C, '']
  • 变量delta_strings保存列表strings和引用字符串ref_string中每个字符串之间的所有增量。
  • 变量selector是一个仅包含10值的列表,0指定不应该打印的排序规则,反之亦然。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25219429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档