将二进制矩阵转换为原始矩阵

transform a binary matrix into the original matrix

我是python的初学者,不知道如何解决这个问题:

我有 60 个核苷酸的 DNA 序列保存在 csv 格式中,其中每个核苷酸由 3 个二进制指示变量替换,如下所示:

A -> 1 0 0
C -> 0 1 0
G -> 0 0 1
T -> 0 0 0

所以我有一个 60*3 列和 ~3000 行的矩阵。

我想回去获取原始 DNA 序列。我该怎么做?

我尝试了以下代码但它崩溃了:

mm_output = pd.DataFrame(columns=['colname_' + str(i) for i in range(60)], index=range(X.shape[0])) 
for i in range(X.shape[0]):
 for j in np.arange(0, 180, 3):
   X_sub=X.iloc[i,j:j+3]
   j_tmp=int(j/3)
    if np.array_equal(X_sub.values,A):
     mm_output.iloc[i,j_tmp]='A'
    elif np.array_equal(X_sub.values,C):
     mm_output.iloc[i,j_tmp]='C'
    elif np.array_equal(X_sub.values,G):
     mm_output.iloc[i,j_tmp]='G'
    elif np.array_equal(X_sub.values,T):
     mm_output.iloc[i,j_tmp]='T'

数据集收集于此:https://www.openml.org/d/40670

提前致谢

看起来您的数据在 X 中,并且根据您链接到的文件,X 的形状为 (3186, 180)。这里有一种方法可以将其转换为形状为 (3186, 60) 的数组,其中包含字符 'A'、'C'、'G' 和 'T'.

首先,请注意,您可以将每个三元组与 [1, 2, 3] 打点(即矩阵相乘),从而将其转换为整数索引。例如,

In [42]: a = np.array([0, 1, 0])

In [43]: a @ [1, 2, 3]  # Convert `a` to the value 2.
Out[43]: 2

In [44]: a = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0]])

In [45]: a
Out[45]: 
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1],
       [0, 0, 0]])

In [46]: a @ [1, 2, 3]  # Convert each row of `a` to a single integer.
Out[46]: array([1, 2, 3, 0])

该矩阵乘积产生的整数可以用作数组的索引,以将它们转换为核苷酸字符。例如

In [47]: nucs = np.array(['T', 'A', 'C', 'G'])

In [48]: nucs[[1, 2, 3, 0]]
Out[48]: array(['A', 'C', 'G', 'T'], dtype='<U1')

要将这些技术应用于数组 X,数组必须从 (3186, 180) 重塑为 (3186, 60, 3)。 (下面使用 -1 告诉 reshape 根据其他值计算出该长度。您也可以将 60 放在那里。)

In [49]: X3 = X.reshape(X.shape[0], -1, 3)

In [50]: X3.shape
Out[50]: (3186, 60, 3)

现在我们可以将矩阵乘法和索引应用于X3。创建索引数组:

In [51]: index = X3 @ [1, 2, 3]

In [52]: index.shape
Out[52]: (3186, 60)

In [53]: index
Out[53]: 
array([[2, 0, 1, ..., 1, 3, 1],
       [3, 3, 0, ..., 0, 1, 2],
       [3, 3, 2, ..., 2, 3, 3],
       ...,
       [3, 3, 2, ..., 3, 2, 1],
       [0, 0, 2, ..., 0, 3, 2],
       [1, 3, 1, ..., 0, 3, 3]])

使用indexnucs将索引转换为核苷酸字符:

In [54]: nucleotides = nucs[index]

In [55]: nucleotides.shape
Out[55]: (3186, 60)

In [56]: nucleotides
Out[56]: 
array([['C', 'T', 'A', ..., 'A', 'G', 'A'],
       ['G', 'G', 'T', ..., 'T', 'A', 'C'],
       ['G', 'G', 'C', ..., 'C', 'G', 'G'],
       ...,
       ['G', 'G', 'C', ..., 'G', 'C', 'A'],
       ['T', 'T', 'C', ..., 'T', 'G', 'C'],
       ['A', 'G', 'A', ..., 'T', 'G', 'G']], dtype='<U1')

如果你想把每一行的符号组合成一个60个字符的字符串,你可以使用

In [57]: sequences = nucleotides.view('U60')[:, 0]

In [58]: sequences.shape
Out[58]: (3186,)

In [59]: sequences
Out[59]: 
array(['CTAGGCTCCAGATAGCCATAGAAGAACCAAACACTTTCTGCGTGTGTGAGAATAATCAGA',
       'GGTGTTGCTCTTAGGATGTATCCCCTCAAACCTACCTGGTGGTTCTGTGCCTTCCCCTAC',
       'GGCTGGACCGACCACAGCGCGTGCAGTAAGTCGGCCCCCTGCCCCGTCCTGCCCTGCCGG',
       ...,
       'GGCCCAGCTGAGGTCTCTCTCTTCTCGCAGTTTCCATGTGGTACACACTCCCCCGCTGCA',
       'TTCAGGGGAAAAAAATATCTTCTTGGCAAGGTAACACACTCTGTAAATGCATGTTCATGC',
       'AGACACAGAAGTCCATCTATTACATCACTGGTGCGTTGACTCTGATTGAAGCCTTTTTGG'],
      dtype='<U60')

这是没有所有中间数据检查的代码:

nucs = np.array(['T', 'A', 'C', 'G'])
X3 = X.reshape(X.shape[0], -1, 3)
index = X3 @ [1, 2, 3]
nucleotides = nucs[index]
sequences = nucleotides.view('U60')[:, 0]