【问题标题】:find gene name from liste to dataframe从列表到数据框查找基因名称
【发布时间】:2018-10-19 17:56:02
【问题描述】:

如果我的结果,我实际上必须知道我是否得到了一些基因,这样做我有一个包含我基因名称的列表和一个相同的数据框:

例如

liste["gene1","gene2","gene3","gene4","gene5"]

和一个数据框:

name1          name2
gene1_0035     gene1_0042
gene56_0042    gene56_0035
gene4_0042     gene4_0035
gene2_0035     gene2_0042
gene57_0042    gene57_0035

然后我做了:

df=pd.read_csv("dataframe_not_max.txt",sep='\t')
df=df.drop(columns=(['Unnamed: 0', 'Unnamed: 0.1']))
#print(df)
print(list(df.columns.values))
name1=df.ix[:,1]
name2=df.ix[:,2]


liste=[]
for record in SeqIO.parse(data, "fasta"):
    liste.append(record.id)

print(liste)
print(len(liste))

count=0
for a, b in zip(name1, name2):

    if a in liste:
        count+=1

    if b in liste: 
        count+=1
print(count)

我想知道我从列表中找到 ma 数据框中的基因有多少次,但它们的 ID 不完全相同,因为在列表中基因名称后没有 _number,那么如果我in liste 不会重新识别 ID。

是否可以这样说:

if a without_number in liste: 

在上面的例子中它是: count = 3,因为列表和数据帧中都只有基因 1,2 和 4。

这里有一个更复杂的例子,看看你的脚本是否确实适用于我的数据: 假设我有一个这样的数据框:

  cluster_name  qseqid  sseqid  pident_x
15  cluster_016607  EOG090X00GO_0035_0035   EOG090X00GO_0042_0035
16  cluster_016607  EOG090X00GO_0035_0035   EOG090X00GO_0042_0042
18  cluster_016607  EOG090X00GO_0035_0042   EOG090X00GO_0042_0035
19  cluster_016607  EOG090X00GO_0035_0042   EOG090X00GO_0042_0042
29  cluster_015707  EOG090X00LI_0035_0035   EOG090X00LI_0042_0042
30  cluster_015707  EOG090X00LI_0035_0035   EOG090X00LI_0042_0035
34  cluster_015707  EOG090X00LI_0042_0035   g1726.t1_0035_0042
37  cluster_015707  EOG090X00LI_0042_0042   g1726.t1_0035_0042

还有一个列表:["EOG090X00LI_","EOG090X00GO_","EOG090X00BA_"]

这里我得到 6,但我应该得到 2,因为我的数据 EOG090X00LI 和 EOG090X00GO 中只有 2 个序列

其实这里我想统计一个序列只出现一次的时候才出现,即使是举例:EOG090X00LI vs seq123454

不知道清楚了吗?

我用的例子:

df=pd.read_csv("test_busco_augus.csv",sep=',')
#df=df.drop(columns=(['Unnamed: 0', 'Unnamed: 0.1']))
print(df)
print(list(df.columns.values))
name1=df.ix[:,3]
name2=df.ix[:,4]

liste=["EOG090X00LI_","EOG090X00GO_","EOG090X00BA_"]

print(liste)


#get boolean mask for each column    
m1 = name1.str.contains('|'.join(liste))
m2 = name2.str.contains('|'.join(liste))

#chain masks and count Trues

a = (m1 & m2).sum()
print (a)

【问题讨论】:

    标签: python pandas loops


    【解决方案1】:

    我认为需要:

    #add _ to end of values
    liste =  [record.id + '_' for record in SeqIO.parse(data, "fasta")]
    #liste = ["gene1_","gene2_","gene3_","gene4_","gene5_"]
    
    #get boolean mask for each column    
    m1 = df['name1'].str.contains('|'.join(liste))
    m2 = df['name2'].str.contains('|'.join(liste))
    
    #chain masks and count Trues
    a = (m1 & m2).sum()
    print (a)
    3
    

    编辑:

    liste=["EOG090X00LI","EOG090X00GO","EOG090X00BA"]
    
    #extract each values before _, remove duplicates and compare by liste   
    a = name1.str.split('_').str[0].drop_duplicates().isin(liste)
    b = name2.str.split('_').str[0].drop_duplicates().isin(liste)
    
    #compare a with a for equal and sum Trues
    c = a.eq(b).sum()
    print (c)
    2
    

    【讨论】:

    • 嗨,谢谢,我更新了我的第一条评论,因为我忘了告诉我只想计算序列 ID 出现一次的时间。
    【解决方案2】:

    针对更新的 OP 进行了调整

    求和等于 1

    df.stack().str.split('_').str[0].isin(liste).sum(level=0).eq(1).sum()
    
    2
    

    旧答案

    stackstr 访问器

    您可以在'_' 上使用split 来抓取第一部分,然后使用isin 来确定成员资格。我还将stackall 与参数level=0 一起使用,以查看所有列的成员资格是否为True

    df.stack().str.split('_').str[0].isin(liste).all(level=0).sum()
    
    3
    

    applymap

    df.applymap(lambda x: x.split('_')[0] in liste).all(1).sum()
    
    3
    

    sum/all 带生成器

    sum(all(x.split('_')[0] in liste for x in r) for r in df.values)
    
    3
    

    两个很多map

    sum(map(lambda r: all(map(lambda x: x.split('_')[0] in liste, r)), df.values))
    
    3
    

    【讨论】:

    • 嗨,谢谢,我更新了我的第一条评论,因为我忘了告诉我只想计算序列 ID 出现一次的时间。
    【解决方案3】:

    使用isin

    df.apply(lambda x : x.str.split('_').str[0],1).isin(l).sum(1).eq(2).sum()
    Out[923]: 3
    

    添加value_counts

    df.apply(lambda x : x.str.split('_').str[0],1).isin(l).sum(1).value_counts()
    Out[925]: 
    2    3
    0    2
    dtype: int64
    

    【讨论】:

    • 嗨,谢谢,我更新了我的第一条评论,因为我忘了告诉我只想计算序列 ID 出现一次的时间。
    • 你好,我不太明白输出,例如3是什么?
    • @Benjamin 两列都显示在列表中,有 3 行,两列都没有显示有 2
    【解决方案4】:

    您可以使用stack() 将您的数据框转换为一个系列(组合所有列),然后使用Series.str.match()liste 后跟下划线_ 中搜索您的基因名称:

    s = df.stack()
    
    sum([s.str.match(i+'_').any() for i in liste])
    

    返回3

    详情:

    df.stack() 返回以下Series

    0  name1     gene1_0035
       name2     gene1_0042
    1  name1    gene56_0042
       name2    gene56_0035
    2  name1     gene4_0042
       name2     gene4_0035
    3  name1     gene2_0035
       name2     gene2_0042
    4  name1    gene57_0042
       name2    gene57_0035
    

    由于您的所有基因在该系列中后跟下划线,您只需要查看gene_name 后跟_ 是否在该系列中。如果是这种情况,s.str.match(i+'_').any() 返回True。然后,您得到 True 值的总和,这就是您的计数。

    【讨论】:

    • 嗨,谢谢,我更新了我的第一条评论,因为我忘了告诉我只想计算序列 ID 出现一次的时间。
    • @Benjamin,在你更新的例子中,我得到了你的预期结果(2),我的代码(只要你的列表在你原来的例子中,ie i> 没有_)
    猜你喜欢
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 2017-12-10
    相关资源
    最近更新 更多