使用python构建树

2024-09-29 02:23:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python新手,正在尝试使用python构建具有父子关系的树。我正面临着艰难的时刻:

数据帧:

data = [['root','Parent1','Children1','Grand Childern 1','Great Grand Childern 1'],['root','Parent1','Children2','Grand Childern 1','Great Grand Childern 1'],['root','Parent1','Children2','Grand Childern 2','Great Grand Childern 1'],['root','Parent2','Children1','Grand Childern 1','Great Grand Childern 1'],['root','Parent2','Children2','Grand Childern 1','Great Grand Childern 1']]

df=pd.DataFrame(data,columns=['LEVEL 1','LEVEL 2','LEVEL 3','LEVEL 4','LEVEL 5'])

我正在尝试转换为JSON树格式,如下所示:

{
"name": "root",
"children": [{ 
    "name": "Parent1",
    "children": [{ 
        "name": "Children1" ,
        "children":[{
            "name":"Grand Children1",
            "children":[{
                "name":"Great Grand Children1"
                }]
            }]},
    { 
        "name": "Children2" , 
        "children":[{
          "name":"Grand Children1",
                "children":[{"name":"Great Grand Children1"}],
          "name":"Grand Children2",
                "children":[{"name":"Great Grand Children1"}]}
          ] }
    ]
  },
  { 
    "name": "Parent2",
    "children": [
      { 
          "name": "Children1" ,
          "children":[{"name":"Grand Children1",
                        "children":[{"name":"Great Grand Children1"}]}] },
      { 
          "name": "Children2" , 
          "children":[{
          "name":"Grand Children1","children":[{"name":"Great Grand Children1"}],
          "name":"Grand Children1","children":[{"name":"Great Grand Children2"}]}
          ] }
    ]
  }]
}

数据帧:

enter image description here

如果有人能帮助我,我将不胜感激


Tags: 数据namedatarootlevelgrandchildren新手
3条回答

作为中间步骤,您可能希望将列表列表(当前不在树的结构中,而是指定树的各个垂直分支)转换为DICT树,其中每个节点都包含对其所有子节点的引用

使用dict从列表列表中构建树,可以非常简单地确保任何给定节点的所有子节点都位于正确的位置(即在该节点下分组):

>>> data = [
    ['root', 'Parent1', 'Children1', 'Grand Childern 1', 'Great Grand Childern 1'],
    ['root', 'Parent1', 'Children2', 'Grand Childern 1', 'Great Grand Childern 1'],
    ['root', 'Parent1', 'Children2', 'Grand Childern 2', 'Great Grand Childern 1'],
    ['root', 'Parent2', 'Children1', 'Grand Childern 1', 'Great Grand Childern 1'],
    ['root', 'Parent2', 'Children2', 'Grand Childern 1', 'Great Grand Childern 1']
]
>>> tree = {}
>>> for row in data:
...     node = tree
...     for cell in row:
...         node = node.setdefault(cell, {})
...
>>> tree
{'root': {
    'Parent1': {
        'Children1': {
            'Grand Childern 1': {
                'Great Grand Childern 1': {}
            }
        }, 
        'Children2': {
            'Grand Childern 1': {
                'Great Grand Childern 1': {}
            }, 
            'Grand Childern 2': {
                'Great Grand Childern 1': {}
            }
        }
    }, 
    'Parent2': {
        'Children1': {
            'Grand Childern 1': {
                'Great Grand Childern 1': {}
            }
        }, 
        'Children2': {
            'Grand Childern 1': {
                'Great Grand Childern 1': {}
            }
        }
    }
}}

现在,您已经拥有了一个实际树结构中的所有内容,将其转换为您需要的任何更具体的格式(例如,所需的JSON)应该很简单

如果它不必来自“Pandas”库,则可以使用“anytree”库创建树,并使用“JSON Exporter”将其导出为JSON

您可以对collections.defaultdict使用递归:

from collections import defaultdict
def to_tree(d):
   _d = defaultdict(list)
   for a, *b in d:
      _d[a].append(b)
   return [{'name':a, 'children':to_tree(k)} if (k:=list(filter(None, b))) else \
                    {'name':a} for a, b in _d.items()]

data = [['root','Parent1','Children1','Grand Childern 1','Great Grand Childern 1'],['root','Parent1','Children2','Grand Childern 1','Great Grand Childern 1'],['root','Parent1','Children2','Grand Childern 2','Great Grand Childern 1'],['root','Parent2','Children1','Grand Childern 1','Great Grand Childern 1'],['root','Parent2','Children2','Grand Childern 1','Great Grand Childern 1']]

import json
print(json.dumps(to_tree(data), indent=4))

输出:

[
  {
    "name": "root",
    "children": [
        {
            "name": "Parent1",
            "children": [
                {
                    "name": "Children1",
                    "children": [
                        {
                            "name": "Grand Childern 1",
                            "children": [
                                {
                                    "name": "Great Grand Childern 1"
                                }
                            ]
                        }
                    ]
                },
                {
                    "name": "Children2",
                    "children": [
                        {
                            "name": "Grand Childern 1",
                            "children": [
                                {
                                    "name": "Great Grand Childern 1"
                                }
                            ]
                        },
                        {
                            "name": "Grand Childern 2",
                            "children": [
                                {
                                    "name": "Great Grand Childern 1"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "name": "Parent2",
            "children": [
                {
                    "name": "Children1",
                    "children": [
                        {
                            "name": "Grand Childern 1",
                            "children": [
                                {
                                    "name": "Great Grand Childern 1"
                                }
                            ]
                        }
                    ]
                },
                {
                    "name": "Children2",
                    "children": [
                        {
                            "name": "Grand Childern 1",
                            "children": [
                                {
                                    "name": "Great Grand Childern 1"
                                }
                            ]
                        }
                    ]
                 }
             ]
          }
      ]
   }
]

不带Python3.8赋值表达式的解决方案:

from collections import defaultdict
def to_tree(d):
   _d = defaultdict(list)
   for a, *b in d:
     _d[a].append(b)
   vals = [[a, list(filter(None, b))] for a, b in _d.items()]
   return [{'name':a, 'children':to_tree(b)} if b else {'name':a} for a, b in vals]

相关问题 更多 >