【问题标题】:Transform character array into integers with python使用python将字符数组转换为整数
【发布时间】:2013-08-04 19:30:36
【问题描述】:

我有一个字符数组形式的数据:

cgcgcg
aacacg
cgcaag
cgcacg
agaacg
cacaag
agcgcg
cgcaca
cacaca
agaacg
cgcacg
cgcgaa

请注意,每列仅包含两种类型的字符。我需要根据它们在列中的百分比将它们转换为整数 0 或 1。比如第一列有8个c和4个a,所以c占多数,那么我们需要把它编码为0,另一个编码为1。

使用 zip() 我可以在 python 中转置这个数组,并将每一列放入一个列表中:

In [28]: lines = [l.strip() for l in open(inputfn)]

In [29]: list(zip(*lines))
Out[29]: 
[('c', 'a', 'c', 'c', 'a', 'c', 'a', 'c', 'c', 'a', 'c', 'c'),
 ('g', 'a', 'g', 'g', 'g', 'a', 'g', 'g', 'a', 'g', 'g', 'g'),
 ('c', 'c', 'c', 'c', 'a', 'c', 'c', 'c', 'c', 'a', 'c', 'c'),
 ('g', 'a', 'a', 'a', 'a', 'a', 'g', 'a', 'a', 'a', 'a', 'g'),
 ('c', 'c', 'a', 'c', 'c', 'a', 'c', 'c', 'c', 'c', 'c', 'a'),
 ('g', 'g', 'g', 'g', 'g', 'g', 'g', 'a', 'a', 'g', 'g', 'a')]

不必将它们严格转换为整数,即“c”到“0”或“c”到 int(0) 都可以,因为我们无论如何都要将它们写入制表符分隔的文件。

【问题讨论】:

  • 我猜,根据你这里的字母,我们说的是 DNA 碱基对?如果是这样,我不得不说,我认为让 0/1 模棱两可不是一个好主意。为什么最常见的核苷酸是“0”很重要? (或者我对 DNA 的看法错了吗?)
  • 如果大多数是g怎么办? c 应该是 1,a 是 0...
  • @AdamKG 是的,这是 DNA 的东西。没有歧义,因为虽然我们有 4 个碱基,但它们总是成对出现,即 A 和 T,C 和 G,所以我们在数据分析时只需要两个数字来表示它们。
  • @septi 多数我的意思是在每一列中,或者在我上面显示的结果中的每个列表中。如果 g 是多数,则表示为 0。由于每个列表中只有两种类型的字符,因此不会发生冲突。
  • 不,我的意思是你的 0 代表 a/t 对还是 c/g 对是模棱两可的。为什么不让它在整个数据集中保持一致?

标签: python data-manipulation


【解决方案1】:

类似这样的:

lis = [('c', 'a', 'c', 'c', 'a', 'c', 'a', 'c', 'c', 'a', 'c', 'c'),
 ('g', 'a', 'g', 'g', 'g', 'a', 'g', 'g', 'a', 'g', 'g', 'g'),
 ('c', 'c', 'c', 'c', 'a', 'c', 'c', 'c', 'c', 'a', 'c', 'c'),
 ('g', 'a', 'a', 'a', 'a', 'a', 'g', 'a', 'a', 'a', 'a', 'g'),
 ('c', 'c', 'a', 'c', 'c', 'a', 'c', 'c', 'c', 'c', 'c', 'a'),
 ('g', 'g', 'g', 'g', 'g', 'g', 'g', 'a', 'a', 'g', 'g', 'a')]
def solve(lis):
    for row in lis:
        item1, item2 = set(row)
        c1, c2 = row.count(item1), row.count(item2)
        dic = {item1 : int(c1 < c2), item2 : int(c2 < c1)}
        yield [dic[x] for x in row]
...         
>>> list(solve(lis))
[[0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1]]

使用collections.Counter

from collections import Counter
def solve(lis):
    for row in lis:
        c = Counter(row)
        maxx = max(c.values())
        yield [int(c[x] < maxx) for x in row]
...         
>>> pprint(list(solve(lis)))
[[0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0],
 [0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
 [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
 [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1]]

【讨论】:

  • 除了字典中的 int(c1 &lt; c2) 之外,一切正常。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-11-11
  • 1970-01-01
  • 2019-11-08
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
相关资源
最近更新 更多