从Pandas为组织结构图创建嵌套JSON

时间:2016-08-18 02:03:16

标签: python json python-3.x

我尝试从分层DataFrame(python 3.5)创建嵌套JSON对象,以提供给JavaScript以呈现组织结构图。我基本上试图创建在这个问题的答案中找到的结构:Organization chart - tree, online, dynamic, collapsible, pictures - in D3

示例数据框:

df = pd.DataFrame({\
'Manager_Name':['Mike' ,'Jon', 'Susan' ,'Susan' ,'Joe'],\
'Manager_Title':['Level1' ,'Level2'  ,'Level3' ,"Level3", 'Level4'],\
'Employee_Name':['Jon' ,'Susan' ,'Josh' ,'Joe' ,'Jimmy'],\
'Employee_Title':["Level2" ,"Level3" ,"Level4" ,"Level4" ,"Level5"]})

所需的输出是:

"Name": "Mike"
"Title": "Level1"
"Employees": [{
        "Name": "Jon"
        "Title": "Level2"
        "Employees": [{
               "Name": "Susan"
               "Title": "Level3"
               "Employees": [{
               ...
               ...
               ...
               }]
      }]
}]

我知道这不是代码生成服务,但我尝试应用其他类似相关的答案,似乎无法在这里应用这些答案。我也没有那么多的词典(我更多的是一个R人),所以这个问题可能有些无趣。我有更多的时间在这上面,但我确信这里有人可以在几分钟内做到这一点。

其他问题:

提前致谢!

1 个答案:

答案 0 :(得分:0)

考虑按级别筛选出数据框,并使用pandas to_dict()将dfs转换为字典,这些pandas会不断汇总到各个级别的列表中。下面定义的函数从最后一级到第一级,以汇总各个Employee Levels字典。但首先你应该连接Manager和Employee Name Title 列。

import json
import pandas as pd

cdf = pd.concat([df[['Manager_Name', 'Manager_Title']].\
            rename(index=str, columns={'Manager_Name':'Name', 'Manager_Title':'Title'}),
            df[['Employee_Name', 'Employee_Title']].\
            rename(index=str, columns={'Employee_Name':'Name', 'Employee_Title':'Title'})])

cdf = cdf.drop_duplicates().reset_index(drop=True)
print(cdf)
#     Name   Title
# 0   Mike  Level1
# 1    Jon  Level2
# 2  Susan  Level3
# 3    Joe  Level4
# 4   Josh  Level4
# 5  Jimmy  Level5

def jsondict():
    inner = ['']
    for i in ['Level5', 'Level4', 'Level3', 'Level2']:            
        if i == 'Level5':
            inner[0] = cdf[cdf['Title']==i].to_dict(orient='records')            
        else:
            tmp = cdf[cdf['Title']==i].copy().reset_index(drop=True)            
            if len(tmp) == 1:
                tmp['Employees'] = [inner[0]]
            else:
                for d in range(0,len(tmp)):
                    tmp.ix[d, 'Employees'] = [inner[0]]                                
            lvltemp = tmp.to_dict(orient='records')
            inner[0] = lvltemp            
    return(inner)

jsondf = cdf[cdf['Title']=='Level1'].copy()
jsondf['Employees'] = jsondict()    
jsondata = jsondf.to_json(orient='records')

<强>输出

[{"Name":"Mike","Title":"Level1","Employees":
[{"Name":"Jon","Title":"Level2","Employees":
[{"Name":"Susan","Title":"Level3","Employees":
[{"Name":"Joe","Title":"Level4","Employees":
[{"Name":"Jimmy","Title":"Level5"}]},
{"Name":"Josh","Title":"Level4","Employees":
[[{"Name":"Jimmy","Title":"Level5"}]]}]}]}]}]

或漂亮印刷

[
  {
    "Name": "Mike",
    "Title": "Level1",
    "Employees": [
      {
        "Name": "Jon",
        "Title": "Level2",
        "Employees": [
          {
            "Name": "Susan",
            "Title": "Level3",
            "Employees": [
              {
                "Name": "Joe",
                "Title": "Level4",
                "Employees": [
                  {
                    "Name": "Jimmy",
                    "Title": "Level5"
                  }
                ]
              },
              {
                "Name": "Josh",
                "Title": "Level4",
                "Employees": [
                  [
                    {
                      "Name": "Jimmy",
                      "Title": "Level5"
                    }
                  ]
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]