Как разобрать словарь, представляющий дендрограмму, чтобы создать другой словарь, представляющий все родительские и дочерние узлы? - PullRequest
0 голосов
/ 11 марта 2020

Я работаю с мышью Аллена Брейна RNA-seq data и из файла dend. json при условии, что я хочу создать словарь, где ключ является родительским узлом, а значение будет быть узлами, на которые родительский узел распадается или ведет к ним. Вы можете увидеть дендрограмму здесь .

Словарь при загрузке файла json выглядит следующим образом:

{'node_attributes': [{'height': 0.8416,
   'members': 290,
   'edgePar.col': '#000000',
   'edgePar.lwd': 2,
   'edgePar.conf': 1,
   'label': '',
   'midpoint': 256.4472,
   'cell_set_accession': 'CS1910120323',
   'cell_set_alias': '',
   'cell_set_designation': 'Neuron/Non-Neuron',
   'X': '291',
   'node_id': 'n1'}],
 'children': [{'node_attributes': [{'height': 0.6271,
     'members': 279,
     'edgePar.col': '#000000',
     'edgePar.lwd': 2,
     'edgePar.conf': 1,
     'label': '',
     'midpoint': 226.7537,
     'cell_set_accession': 'CS1910120324',
     'cell_set_alias': '',
     'cell_set_designation': 'Neuron/Non-Neuron',
     'X': '292',
     'node_id': 'n2'}],
   'children': [{'node_attributes': [{'height': 0.365,
       'members': 271,
       'edgePar.col': '#000000',
       'edgePar.lwd': 2,
       'edgePar.conf': 1,
       'label': '',
       'midpoint': 178.695,
       'cell_set_accession': 'CS1910120325',
       'cell_set_alias': '',
       'cell_set_designation': 'Neuron 001-271',
       'X': '293',
       'node_id': 'n3'}],............

и dictionary['children'][0] следует за левым разделением, и если в узле есть два разделения, dictionary['children'][1] следует за правильным разделением.

Я хочу, чтобы форма вывода была чем-то вроде:

{n1 : [n2, n281],
 n2 : [n3, n284],...}

В данный момент я Я просто могу разобрать словарь и вернуть узлы, используя код, адаптированный из другого поста:

def walk(d):

    for k,v in d.items():
        if isinstance(v, str) or isinstance(v, int) or isinstance(v, float):
            if k == 'node_id':
                print('node:', v)
        elif isinstance(v, list):
            for v_int in range(len(v)):
                walk(v[v_int])

walk(dend)

Output:
node: n1
node: n2
node: n3
node: n4
node: n183
node: n184
node: n185

1 Ответ

1 голос
/ 12 марта 2020

Это может быть близко к тому, что вы хотите.

https://github.com/danielsf/AllenInstTools_by_SFD/blob/master/parse_dendrogram.py

Он создает класс CellNode, который хранит для каждого узла в дендрограмме: имя (cell_set_accession) узла, а также списки имен для всех предков, потомков (непосредственных потомков) и конечных потомков ( всех узлов, произошедших от текущего узла) в дерево. Метод build_tree возвратит диктовку на cell_set_accession, значения которой CellNode для этого узла.

Если вам не нравится использовать cell_set_accession в качестве имени для узлов, Вы можете изменить это в строке 120 скрипта.

Если вам нужно больше или меньше информации в вашем файле, вы можете определить конечные узлы, потому что они будут возвращать пустые списки для node.children.

Код был достаточно хорош для моих целей (это хороший способ сказать, что я не проверял его строго). Не стесняйтесь обращаться, если что-то не работает, как ожидалось.

...