在Numpy数组中的一个标题下合并两列

时间:2013-05-22 13:29:36

标签: python arrays numpy

我有两个Numpy数组,我需要合并只维护A - (888, 1114253)中的某些列,具体取决于B中的行 - size (555861, 3)

问题是A的标题是55730:每列有两个值!

换句话说,我想只获取A的列,其中标题对应于B中的行,但在A中,每列都是“双”

一个例子将澄清:

A

family id mum dad  rs1  rs2  rs3  rs4  rs5  rs6  rs7  rs8  rs9  rs10  rs11  rs12
     1  1   4   6   A T  A A  T T  C C  G G  A T  A G  A A  G A  T A  G G  C C 
     2  2   7   9   T A  G A  C T  C T  G A  T T  A A  A C  G G  T A  C C  C T 
     3  3   2   8   T T  G G  C T  C T  G G  A T  A G  A C  G G  T T  C C  C C 
     4  4   5   1   A A  A A  T T  C C  G A  T T  A A  A A  G A  T A  G C  C T 

由于在这个文件中每个rsxxx列标题有两个对应的列,我必须找到一种方法将它们放在一起,所以我可以将文件作为数组读取

B

1  rs1 2345
1  rs2 2346
2  rs5 2348
4  rs8 2351
4 rs12 2360

所需的输出是

Output

 family id mum dad  rs1 rs2 rs5 rs8 rs12
  1      1   4   6  A T A A G G A A C C
  2      2   7   9  T A G A G A A C C T
  3      3   2   8  T T G G G G A C C C
  4      4   5   1  A A A A G A A A C T

想法?

在控制台上

B

array([['1', 'rs3094315', '752566'],
       ['1', 'rs12562034', '768448'],
       ['1', 'rs3934834', '1005806'],
       ..., 
       ['23', 'rs2032612', '21866491'],
       ['23', 'rs2032621', '21872738'],
       ['23', 'rs2032617', '21896261']], 
      dtype='<S10')

1 个答案:

答案 0 :(得分:2)

看起来每个列由两个空格分隔,但每个基因对由一个空格分隔。如果是这样,你可以使用

delimiter='  '   #two spaces
np.loadtxt中的

import numpy as np
from StringIO import StringIO # for example file

a = StringIO("""family  id  mum  dad  rs1  rs2  rs3  rs4  rs5  rs6  rs7  rs8  rs9  rs10  rs11  rs12
1  1   4   6   A T  A A  T T  C C  G G  A T  A G  A A  G A  T A  G G  C C 
2  2   7   9   T A  G A  C T  C T  G A  T T  A A  A C  G G  T A  C C  C T 
3  3   2   8   T T  G G  C T  C T  G G  A T  A G  A C  G G  T T  C C  C C 
4  4   5   1   A A  A A  T T  C C  G A  T T  A A  A A  G A  T A  G C  C T """)


nrs = 12        # number of `rs` columns, for dtype
dt = 'int,'*4 + 'S10,'*nrs

A = np.genfromtxt(a, delimiter='  ', names=True, dtype=dt)

A

array([ (1, 1, 4, 6, ' A T', 'A A', 'T T', 'C C', 'G G', 'A T', 'A G', 'A A', 'G A', 'T A', 'G G', 'C C'),
       (2, 2, 7, 9, ' T A', 'G A', 'C T', 'C T', 'G A', 'T T', 'A A', 'A C', 'G G', 'T A', 'C C', 'C T'),
       (3, 3, 2, 8, ' T T', 'G G', 'C T', 'C T', 'G G', 'A T', 'A G', 'A C', 'G G', 'T T', 'C C', 'C C'),
       (4, 4, 5, 1, ' A A', 'A A', 'T T', 'C C', 'G A', 'T T', 'A A', 'A A', 'G A', 'T A', 'G C', 'C T')], 
      dtype=[('family', '<i8'), ('id', '<i8'), ('mum', '<i8'), ('dad', '<i8'), ('rs1', 'S10'), ('rs2', 'S10'), ('rs3', 'S10'), ('rs4', 'S10'), ('rs5', 'S10'), ('rs6', 'S10'), ('rs7', 'S10'), ('rs8', 'S10'), ('rs9', 'S10'), ('rs10', 'S10'), ('rs11', 'S10'), ('rs12', 'S10')])

然后,只访问B中的列,执行以下操作:

b = StringIO("""1  rs1 2345
1  rs2 2346
2  rs5 2348
4  rs8 2351
4 rs12 2360""")

B = np.genfromtxt(b, usecols=[1], dtype='S10')

现在,使用A[B]

A[B]
array([(' A T', 'A A', 'G G', 'A A', 'C C'),
       (' T A', 'G A', 'G A', 'A C', 'C T'),
       (' T T', 'G G', 'G G', 'A C', 'C C'),
       (' A A', 'A A', 'G A', 'A A', 'C T')], 
      dtype=[('rs1', 'S10'), ('rs2', 'S10'), ('rs5', 'S10'), ('rs8', 'S10'), ('rs12', 'S10')])

或者,如果您也想要前四列:

A[['family', 'id', 'mum', 'dad'] + list(B)]
array([(1, 1, 4, 6, ' A T', 'A A', 'G G', 'A A', 'C C'),
       (2, 2, 7, 9, ' T A', 'G A', 'G A', 'A C', 'C T'),
       (3, 3, 2, 8, ' T T', 'G G', 'G G', 'A C', 'C C'),
       (4, 4, 5, 1, ' A A', 'A A', 'G A', 'A A', 'C T')], 
      dtype=[('family', '<i8'), ('id', '<i8'), ('mum', '<i8'), ('dad', '<i8'), ('rs1', 'S10'), ('rs2', 'S10'), ('rs5', 'S10'), ('rs8', 'S10'), ('rs12', 'S10')])