สร้างต้นไม้โดยใช้ 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"}]}
          ] }
    ]
  }]
}

ดาต้าเฟรม:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันขอขอบคุณถ้าใครสามารถช่วยฉัน


person Sanjay Chintha    schedule 07.05.2020    source แหล่งที่มา
comment
เป็นการดีที่จะแสดงให้คุณเห็นว่าโค้ดของคุณอยู่ที่ไหน และอธิบายว่าโค้ดใดใช้ไม่ได้กับโค้ดนั้น มิฉะนั้น ดูเหมือนว่าคุณต้องการให้เราทำงานแทนคุณ ซึ่งแน่นอนว่าเราจะไม่ทำ!   -  person Thierry Lathuille    schedule 07.05.2020


คำตอบ (3)


คุณสามารถใช้การเรียกซ้ำกับ 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]
person Ajax1234    schedule 07.05.2020
comment
line : return [{'name':a, 'children':to_tree(k)} if (k:=list(filter(None, b))) else \ {'name':a} สำหรับ a, b ใน _d .items()] ไม่ทำงาน มันทำให้ฉันเกิดข้อผิดพลาดทางไวยากรณ์ที่ 'k' - person Sanjay Chintha; 08.05.2020
comment
@ImSanjay k ใช้ในนิพจน์การมอบหมายซึ่งมีเฉพาะใน Python3.8 เท่านั้น โปรดดูการแก้ไขล่าสุดของฉัน เนื่องจากฉันได้เพิ่มโซลูชันที่จะเข้ากันได้กับเวอร์ชัน ‹ Python3.8 - person Ajax1234; 08.05.2020
comment
ยังคงส่งข้อผิดพลาด AttributeError: วัตถุ 'รายการ' ไม่มีแอตทริบิวต์ 'รายการ' - person Sanjay Chintha; 08.05.2020
comment
เราสามารถเพิ่มชื่อคอลัมน์หลังแอตทริบิวต์ 'ชื่อ' ได้หรือไม่ @อาแจ็กซ์1234 - person Sanjay Chintha; 10.06.2020

หากไม่จำเป็นต้องมาจากไลบรารี "Pandas" คุณสามารถใช้ไลบรารี 'anytree' ได้ เพื่อสร้างแผนผังของคุณและ 'JSON Exporter' เพื่อส่งออกไปยัง เจสัน

person shu    schedule 07.05.2020

ในขั้นตอนกลาง คุณอาจต้องการแปลงรายการของคุณ (ซึ่งปัจจุบันไม่ได้อยู่ในโครงสร้างของแผนผัง แต่ระบุกิ่งก้านแนวตั้งแต่ละกิ่งของต้นไม้) ไปเป็นแผนผังของ dicts โดยที่แต่ละโหนดมีการอ้างอิงไปยังรายการทั้งหมด โหนดย่อย

การใช้ 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 ที่ต้องการ)

person Samwise    schedule 07.05.2020