Как мне преобразовать рекурсию в итерацию для этого кода, который преобразует объект scipy tree в json? - PullRequest
1 голос
/ 25 марта 2019

Я пытаюсь преобразовать объект дерева Scipy (возвращенный из метода to_tree scipy) в json, чтобы я мог визуализировать дендрограмму в D3.По сути, я пытаюсь сделать то же самое, что и:

scipy dendrogram для json для визуализации дерева d3.js

Ответ, предложенный mdml, работает отлично, но егоОтвет использует рекурсию в методе add_node.Когда данные большие, они выдают RuntimeError: maximum recursion depth exceeded.

. Поэтому я пытаюсь реализовать add_node, используя итерацию вместо рекурсии.

Следующий код - это то, что я пробовал, но он не дает мне правильного результата.После каждой итерации словарь 'info' должен быть присвоен списку 'children', но проблема в том, что я не знаю, как перейти к внутреннему уровню потомков после каждой итерации.Как показано в ожидаемом результате ниже, есть «дети» внутри «детей» и так далее.

Так что же мне делать, чтобы назначать «информацию» правильным «потомкам» после каждой итерации?

import pandas as pd 
import scipy.spatial
import scipy.cluster
import numpy as np
import json
import matplotlib.pyplot as plt
from functools import reduce

geneExp = {'genes' : ['a', 'b', 'c', 'd', 'e', 'f'],
       'exp1': [-2.2, 5.6, 0.9, -0.23, -3, 0.1],
       'exp2': [5.4, -0.5, 2.33, 3.1, 4.1, -3.2]
          }
df = pd.DataFrame( geneExp )
dataMatrix = np.array( df[['exp1', 'exp2']] )
distMat = scipy.spatial.distance.pdist( dataMatrix )

clusters = scipy.cluster.hierarchy.linkage(distMat, method='single')
T = scipy.cluster.hierarchy.to_tree( clusters , rd=False )
D = dict(children=[], name="Root1")
Nodes = [T]
while(1):
    for node in Nodes:
        if node.is_leaf()==True:
            info = dict(node_id=node.id,children=[])
            D['children'].append(info)
        else:
            if len(D['children'])>0:
                info = dict(node_id=node.id,children=[])
                D['children'].append(info)
                T1 = T.get_right()
                T2 = T.get_left()
                newNodes = [T1,T2]
                D = D['children'][0]   ### ???
                Nodes = newNodes
            else:
                info = dict(node_id=node.id,children=[])
                D['children'].append(info)
                T1 = T.get_right()
                T2 = T.get_left()
                newNodes = [T1,T2]
                D = D['children'][0]   ### ???
                Nodes = newNodes

Это ожидаемый результат.

{'children': [{'node_id': 10,
   'children': [{'node_id': 5, 'children': []},
    {'node_id': 9,
     'children': [{'node_id': 1, 'children': []},
      {'node_id': 8,
       'children': [{'node_id': 6,
         'children': [{'node_id': 2, 'children': []},
          {'node_id': 3, 'children': []}]},
        {'node_id': 7,
         'children': [{'node_id': 0, 'children': []},
          {'node_id': 4, 'children': []}]}]}]}]}],
 'name': 'Root1'}
...