在矩阵中管理和子串接多个字符串(Python和Numpy)

在矩阵中管理和子串接多个字符串(Python和Numpy),python,numpy,substring,Python,Numpy,Substring,我有一个名为“test.fa”的文件,内容如下: >Sequence 1 TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT >Sequence 2 CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG >Sequence 3 TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG >Sequence 4 AAAACACTTGAGGGAGCAGATAACTGGGCCAACCAT

我有一个名为“test.fa”的文件,内容如下:

>Sequence 1
TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT
>Sequence 2
CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG
>Sequence 3
TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG
>Sequence 4
AAAACACTTGAGGGAGCAGATAACTGGGCCAACCATGACTC
此测试文件只有8行,但可以有更多行。我现在也不知道所有序列的长度。首先我计算行数,然后根据行数创建一个矩阵

import numpy as np
filename = "test.fa"
with open(filename, 'r') as file:
    n1 = 0
    n2 = 0
    for line in file.readlines():
        if line[0] != '>':
            m1 = 1
            n1 = n1 + m1
        else:
            m2 = 1
            n2 = n2 + m2
    seq = np.chararray((n1,2),itemsize = 99)
接下来,我向矩阵中添加值

with open(filename, 'r') as file:
    n3 = -1
    n4 = -1
    for line in file.readlines():
        if line[0] != '>':
            m3 = 1
            n3 = n3 + m3
            seq[n3,1] = line
        else:
            m4 = 1
            n4 = n4 + m4
            seq[n4,0] = line
如果我叫‘seq’,我会得到:

chararray([[b'>Sequence 1', b'TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT'],
       [b'>Sequence 2', b'CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG'],
       [b'>Sequence 3', b'TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG'],
       [b'>Sequence 4', b'AAAACACTTGAGGGAGCAGATAACTGGGCCAACCATGACTC']], dtype='|S99')

seq[2,1]: b'TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG'
seq[2,1][0] : 84
seq[2,1][0:8] : b'TCGACCCT'
seq[2,8][8] : 67
seq[2,1][8:9] : C
这并不是管理这些数据的最佳方式(为什么[2,1][0]返回84?)。我不确定itemsize为99的np.chararray是否是最好的方法


我的问题是:组织/管理这些数据的更好方法是什么?我最终需要计算每个核苷酸的出现次数(即As、Ts、Cs、Gs的数量),并从每个序列中提取子串。就上下文而言,这与期望最大化和吉布斯抽样有关。

我刚刚发现了这篇论文,也许它会帮助你继续寻找。

TL;博士


python

它返回84,而类型是S99,因为找到的最大长度是99,所以类型应该是S99,您从文件中读取的方式不太正确,管理您的数据的更好方法是使用
dict
,我不知道它是否适合您的下一个需要,但这里是:

seq={}
with open("file") as f:
    for line in f:
        seq[line]=next(f)

在这里,它将一次读取两行,因此第一行具有序列1,下一行(f)具有序列TGC….,如果文件顺序不一致,则使用if语句通过使用
np.chararray
,您将获得一个带有
S
dtype的数组,bytestrings:

In [145]: x = np.chararray((1,),10)                                                            
In [146]: x[0]='ACT'                                                                           
In [147]: x                                                                                    
Out[147]: chararray([b'ACT'], dtype='|S10')
In [148]: x[0]                                                                                 
Out[148]: b'ACT'
In [149]: x[0][0]                                                                              
Out[149]: 65
In [150]: x[0][1]                                                                              
Out[150]: 67
In [151]: x[0][2]                                                                              
Out[151]: 84
这是每个字符一个字节。
A
的ASCII码为65<代码>T是19个字符

您是否看到
chararray
注释:

chararray
类的存在是为了向后兼容 Numaray,不建议进行新开发。从努比开始 1.4,如果需要字符串数组,建议使用字符串数组
dtype
对象
字符串
unicode
,并使用自由函数 在
numpy.char
模块中,用于快速矢量化字符串操作

如果改为使用Py3默认字符串类型(unicode):

因此,这些字符串的基本处理:

In [171]: [len(val) for key,val in alist]                                                      
Out[171]: [41, 41, 44, 41]
In [172]: [val.count('T') for key,val in alist]                                                
Out[172]: [16, 7, 6, 6]
In [173]: [val.count('C') for key,val in alist]                                                
Out[173]: [12, 21, 15, 10]

seq[2,1][0]返回84,这是T的十进制ascii码(seq[2,1][0]),我认为
numpy
数组对您帮助不大。列表和python字符串更适合逐行创建和查找子字符串。使用list和list.append,您不需要读取文件两次。您不必担心numpy字符串数据类型的固定字符串大小。
In [154]: x = np.array(['ACT'])                                                                
In [155]: x                                                                                    
Out[155]: array(['ACT'], dtype='<U3')
In [156]: x[0]                                                                                 
Out[156]: 'ACT'
In [157]: x[0][0]                                                                              
Out[157]: 'A'
In [158]: x[0][1]                                                                              
Out[158]: 'C'
In [165]: txt = """>Sequence 1 
     ...: TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT 
     ...: >Sequence 2 
     ...: CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG 
     ...: >Sequence 3 
     ...: TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG 
     ...: >Sequence 4 
     ...: AAAACACTTGAGGGAGCAGATAACTGGGCCAACCATGACTC"""                                         
In [166]: alist = []                                                                           
In [167]: for row in txt.splitlines(): 
     ...:     if row.startswith('>'): 
     ...:         x = [row] 
     ...:     else: 
     ...:         x.append(row) 
     ...:         alist.append(x) 
     ...:                                                                                      
In [168]: alist                                                                                
Out[168]: 
[['>Sequence 1', 'TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT'],
 ['>Sequence 2', 'CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG'],
 ['>Sequence 3', 'TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG'],
 ['>Sequence 4', 'AAAACACTTGAGGGAGCAGATAACTGGGCCAACCATGACTC']]
In [169]: dd = {key:val for key,val in alist}                                                  
In [170]: dd                                                                                   
Out[170]: 
{'>Sequence 1': 'TCAGAACCAGTTATAAATTTATCATTTCCTTCTCCACTCCT',
 '>Sequence 2': 'CCCACGCAGCCGCCCTCCTCCCCGGTCACTGACTGGTCCTG',
 '>Sequence 3': 'TCGACCCTCTGGAACCTATCAGGGACCACAGTCAGCCAGGCAAG',
 '>Sequence 4': 'AAAACACTTGAGGGAGCAGATAACTGGGCCAACCATGACTC'}
In [171]: [len(val) for key,val in alist]                                                      
Out[171]: [41, 41, 44, 41]
In [172]: [val.count('T') for key,val in alist]                                                
Out[172]: [16, 7, 6, 6]
In [173]: [val.count('C') for key,val in alist]                                                
Out[173]: [12, 21, 15, 10]