gpt4 book ai didi

json - scipy dendrogram 到 json 用于 d3.js 树可视化

转载 作者:行者123 更新时间:2023-12-04 02:02:15 27 4
gpt4 key购买 nike

我正在尝试将 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()

最佳答案

您可以分三个步骤执行此操作:

  • 递归构造一个嵌套字典,表示 Scipy 的 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 树状图

    The dendrogram output by SciPy.

    D3 树状图

    The dendrogram output by d3

    关于json - scipy dendrogram 到 json 用于 d3.js 树可视化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19964266/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com