Я пытаюсь преобразовать объект дерева Scipy (возвращенный из метода scipy to_tree) в json, чтобы я мог визуализировать дендрограмму в D3. В принципе, я пытаюсь сделать то же самое, что и:
дендрограмма scipy в json для визуализации дерева d3.js
Ответ, предложенный mdml, отлично работает, но в его ответе используется рекурсия в методе add_node. Когда данные большие, будет выброшено RuntimeError: maximum recursion depth exceeded
.
Итак, я пытаюсь реализовать add_node, используя итерацию вместо рекурсии.
Следующий код - это то, что я пробовал, но он не дает мне правильного результата. После каждой итерации словарь «info» должен быть назначен списку «дочерние элементы», но проблема в том, что я не знаю, как перейти к самому внутреннему уровню дочерних элементов после каждой итерации. Как показано в ожидаемом результате ниже, внутри «детей» есть «дети» и так далее.
Итак, что мне делать, чтобы назначать «информацию» правильным «потомкам» после каждой итерации?
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'}