Построить дерево, используя python - PullRequest
0 голосов
/ 07 мая 2020

Я новичок в 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"}]}
          ] }
    ]
  }]
}

DataFrame:

enter image description here

Я ценю, если кто-нибудь может мне помочь.

Ответы [ 3 ]

0 голосов
/ 07 мая 2020

Если это не обязательно из библиотеки «Pandas», вы можете использовать библиотеку ' anytree ' для создания своего дерева и 'JSON Exporter ' для экспорта в JSON.

0 голосов
/ 07 мая 2020

Вы можете использовать рекурсию с 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]
0 голосов
/ 07 мая 2020

В качестве промежуточного шага вы можете захотеть преобразовать свой список списков (который в настоящее время не входит в структуру дерева, а скорее определяет отдельные вертикальные ветви дерева) в дерево словарных статей, где каждый узел содержит ссылки на все его дочерние узлы.

Использование 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': {}
            }
        }
    }
}}

Теперь, когда у вас есть все в структуре, которая представляет собой реальное дерево, его должно быть просто преобразовать в любой более конкретный формат c, который вам нужен (например, желаемый JSON).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...