python - 如何从 Taxid 获取分类等级名称?

标签 python bioinformatics ncbi etetoolkit

此问题涉及: How to get taxonomic specific ids for kingdom, phylum, class, order, family, genus and species from taxid?

那里给出的解决方案有效,但我想为定义的排名提供每个分类 ID 的名称。我在 ete3 上找到了这个可以完成这项工作:

names = ncbi.get_taxid_translator(lineage)
print [names[taxid] for taxid in lineage]

但不是 python 程序员,我未能将其合并到上面链接中给出的代码中。这是我尝试过的:

import csv
from ete3 import NCBITaxa

ncbi = NCBITaxa()

def get_desired_ranks(taxid, desired_ranks):
    lineage = ncbi.get_lineage(taxid)
    print lineage
    #[1, 131567, 2157, 28890, 183925, 2158, 2159, 2160, 2162, 1204725]
    names = ncbi.get_taxid_translator(lineage)
    print names
    #{1: u'root', 2157: u'Archaea', 2158: u'Methanobacteriales', 2159: u'Methanobacteriaceae', 2160: u'Methanobacterium', 2162: u'Methanobacterium formicicum', 183925: u'Methanobacteria', 28890: u'Euryarchaeota', 131567: u'cellular organisms', 1204725: u'Methanobacterium formicicum DSM 3637'}
    lineage2ranks = ncbi.get_rank(names)
    print lineage2ranks
    #{1: u'no rank', 2157: u'superkingdom', 2158: u'order', 2159: u'family', 2160: u'genus', 2162: u'species', 183925: u'class', 28890: u'phylum', 131567: u'no rank', 1204725: u'no rank'}
    ranks2lineage = dict((rank,taxid) for (taxid, rank) in lineage2ranks.items())
    print ranks2lineage
    return{'{}_id'.format(rank): ranks2lineage.get(rank, '<not present>') for rank in desired_ranks}

def main(taxids, desired_ranks, path):
    with open(path, 'w') as csvfile:
        fieldnames = ['{}_id'.format(rank) for rank in desired_ranks]
    writer = csv.DictWriter(csvfile, delimiter='\t', fieldnames=fieldnames)
        writer.writeheader()
        for taxid in taxids:
            writer.writerow(get_desired_ranks(taxid, desired_ranks))

if __name__ == '__main__':
    taxids = [1204725, 2162,  1300163, 420247]
    desired_ranks = ['kingdom', 'phylum', 'class', 'order', 'family', 'genus', 'species']
    path = 'taxids.csv'
    main(taxids, desired_ranks, path)

非常感谢您提供的任何帮助。

最佳答案

让我们保留您的taxids 不变。

taxids = [1204725, 2162,  1300163, 420247]

然后为每个单独的taxid调用get_desired_ranks

for taxid in taxids:
    ranks = get_desired_ranks(taxid, desired_ranks)

现在为ranks中的每个key(排名)调用ncbi.get_taxid_translator打印输出:

for taxid in taxids:
    print(ncbi.get_taxid_translator([taxid]))
    ranks = get_desired_ranks(taxid, desired_ranks)
    for key, rank in ranks.items():
        if rank != '<not present>':
            print(ncbi.get_taxid_translator([rank]))

输出

{1204725: 'Methanobacterium formicicum DSM 3637'}
{183925: 'Methanobacteria'}
{2159: 'Methanobacteriaceae'}
{2160: 'Methanobacterium'}
{28890: 'Euryarchaeota'}
{2162: 'Methanobacterium formicicum'}
{2158: 'Methanobacteriales'}
{2162: 'Methanobacterium formicicum'}
[...]      
{420247: 'Methanobrevibacter smithii ATCC 35061'}
{183925: 'Methanobacteria'}
{2159: 'Methanobacteriaceae'}
{2172: 'Methanobrevibacter'}
{28890: 'Euryarchaeota'}
{2173: 'Methanobrevibacter smithii'}
{2158: 'Methanobacteriales'}

具有改进输出的完整代码

import csv
from ete3 import NCBITaxa

ncbi = NCBITaxa()

def get_desired_ranks(taxid, desired_ranks):
    lineage = ncbi.get_lineage(taxid)   
    names = ncbi.get_taxid_translator(lineage)
    lineage2ranks = ncbi.get_rank(names)
    ranks2lineage = dict((rank,taxid) for (taxid, rank) in lineage2ranks.items())
    return{'{}_id'.format(rank): ranks2lineage.get(rank, '<not present>') for rank in desired_ranks}

if __name__ == '__main__':
    taxids = [1204725, 2162,  1300163, 420247]
    desired_ranks = ['kingdom', 'phylum', 'class', 'order', 'family', 'genus', 'species']
    for taxid in taxids:
        print(list(ncbi.get_taxid_translator([taxid]).values())[0])
        ranks = get_desired_ranks(taxid, desired_ranks)
        for key, rank in ranks.items():
            if rank != '<not present>':
                print(key + ': ' + list(ncbi.get_taxid_translator([rank]).values())[0])
        print('=' * 60)

如果您想要制表符分隔的输出,您可以使用 \t 连接字符串,或者将所有结果添加到 listjoin\t

在下面的代码片段中,结果存储在名为 resultslist 中,其中包含另一个存储您的字段(原始 ID、王国等)的列表。在每个循环中,结果都会添加到最后一个条目 (results[-1])。

if __name__ == '__main__':
    taxids = [1204725, 2162,  1300163, 420247]
    desired_ranks = ['kingdom', 'phylum', 'class', 'order', 'family', 'genus', 'species']
    results = list()
    for taxid in taxids:
        results.append(list())
        results[-1].append(str(taxid))
        ranks = get_desired_ranks(taxid, desired_ranks)
        for key, rank in ranks.items():
            if rank != '<not present>':
                results[-1].append(list(ncbi.get_taxid_translator([rank]).values())[0])
            else:
                results[-1].append(rank)

    #generate the header
    header = ['Original_query_taxid']
    header.extend(desired_ranks)
    print('\t'.join(header))

    #print the results
    for result in results:
        print('\t'.join(result))

输出

Original_query_taxid    kingdom phylum  class   order   family  genus   species
1204725 Methanobacterium formicicum     Methanobacteriaceae     Euryarchaeota
Methanobacteria Methanobacteriales      Methanobacterium        <not present>
2162    Methanobacterium formicicum     Methanobacteriaceae     Euryarchaeota
Methanobacteria Methanobacteriales      Methanobacterium        <not present>
1300163 Methanobacterium formicicum     Methanobacteriaceae     Euryarchaeota
Methanobacteria Methanobacteriales      Methanobacterium        <not present>
420247  Methanobrevibacter smithii      Methanobacteriaceae     Euryarchaeota
Methanobacteria Methanobacteriales      Methanobrevibacter      <not present>

关于python - 如何从 Taxid 获取分类等级名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43867631/

相关文章:

c++ - 如何设置 QNetworkReply 属性以获得正确的 NCBI 页面?

传递 header /库后未构建 Python 2.7.3 _sqlite3 模块

python - biopython 没有名为 Bio 的模块

r - 基于多列折叠 data.table

python - 预期的 str、bytes 或 os.PathLike 对象,而不是 InMemoryUploadedFile

r - 从数据库检索数据的函数出错

python - 属性错误: 'Ui_Form' object has no attribute 'printHam_btn'

Python 'string' % [1, 2, 3] 不会引发 TypeError

python - Django:与 factory_boy 的一对一字段:UNIQUE 约束失败

python - 匹配正则表达式(python)