我正在尝试将scipy层次聚类的结果转换为json,以便在d3.js中显示an example
以下代码生成具有6个分支的树形图。
import pandas as pd
import scipy.spatial
import scipy.cluster
d = {'employee' : ['A', 'B', 'C', 'D', 'E', 'F'],
'skillX': [2,8,3,6,8,10],
'skillY': [8,15,6,9,7,10]}
d1 = pd.DataFrame(d)
distMat = xPairWiseDist = scipy.spatial.distance.pdist(np.array(d1[['skillX', 'skillY']]), 'euclidean')
clusters = scipy.cluster.hierarchy.linkage(distMat, method='single')
dendo = scipy.cluster.hierarchy.dendrogram(clusters, labels = list(d1.employee), orientation = 'right')
dendo
我的问题 如何以d3.js理解
的格式表示json文件中的数据{'name': 'Root1’,
'children':[{'name' : 'B'},
{'name': 'E-D-F-C-A',
'children' : [{'name': 'C-A',
'children' : {'name': 'A'},
{'name' : 'C'}]
}
}
]
}
令人尴尬的事实是,我不知道我是否可以从dendogram或linkage matrix 以及如何
中提取此信息我感谢能得到的任何帮助。
编辑以澄清
到目前为止,我已尝试使用totree方法,但难以理解其结构(是的,我阅读了文档)。
a = scipy.cluster.hierarchy.to_tree(clusters , rd=True)
for x in a[1]:
#print x.get_id()
if x.is_leaf() != True :
print x.get_left().get_id(), x.get_right().get_id(), x.get_count()
答案 0 :(得分:12)
您可以分三步完成:
to_tree
方法返回的树。dump
生成的嵌套字典到JSON并加载到d3。构造一个代表树形图的嵌套字典
第一步,使用to_tree
调用rd=False
非常重要,以便返回树形图的根。从该根开始,您可以按如下方式构造嵌套字典:
# Create a nested dictionary from the ClusterNode's returned by SciPy
def add_node(node, parent ):
# First create the new node and append it to its parent's children
newNode = dict( node_id=node.id, children=[] )
parent["children"].append( newNode )
# Recursively add the current node's children
if node.left: add_node( node.left, newNode )
if node.right: add_node( node.right, newNode )
T = scipy.cluster.hierarchy.to_tree( clusters , rd=False )
d3Dendro = dict(children=[], name="Root1")
add_node( T, d3Dendro )
# Output: => {'name': 'Root1', 'children': [{'node_id': 10, 'children': [{'node_id': 1, 'children': []}, {'node_id': 9, 'children': [{'node_id': 6, 'children': [{'node_id': 0, 'children': []}, {'node_id': 2, 'children': []}]}, {'node_id': 8, 'children': [{'node_id': 5, 'children': []}, {'node_id': 7, 'children': [{'node_id': 3, 'children': []}, {'node_id': 4, 'children': []}]}]}]}]}]}
基本思想是从不在树形图中的节点开始,该节点将作为整个树形图的根。然后我们递归地将左右孩子添加到这本字典中,直到我们到达树叶。此时,我们没有节点的标签,所以我只是用它们的clusterNode ID标记节点。
标记树形图
接下来,我们需要使用node_ids来标记树形图。评论应该足以说明这是如何运作的。
# Label each node with the names of each leaf in its subtree
def label_tree( n ):
# If the node is a leaf, then we have its name
if len(n["children"]) == 0:
leafNames = [ id2name[n["node_id"]] ]
# If not, flatten all the leaves in the node's subtree
else:
leafNames = reduce(lambda ls, c: ls + label_tree(c), n["children"], [])
# Delete the node id since we don't need it anymore and
# it makes for cleaner JSON
del n["node_id"]
# Labeling convention: "-"-separated leaf names
n["name"] = name = "-".join(sorted(map(str, leafNames)))
return leafNames
label_tree( d3Dendro["children"][0] )
转储到JSON并加载到D3
最后,在树形图被标记后,我们只需将其输出到JSON并加载到D3中。我只是粘贴Python代码将其转储到JSON以获得完整性。
# Output to JSON
json.dump(d3Dendro, open("d3-dendrogram.json", "w"), sort_keys=True, indent=4)
<强>输出强>
我在下面创建了Scipy和D3版本的树形图。对于D3版本,我只是将输出的JSON文件('d3-dendrogram.json'
)插入此Gist。
SciPy树状图
D3树形图