【问题标题】:Create tree structure from csv data for collapse menu从 csv 数据创建树结构以用于折叠菜单
【发布时间】:2021-07-15 19:28:44
【问题描述】:
from collections import defaultdict
import pandas as pd
    df = pd.DataFrame(data)
    d = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(list))))

    for row in df.itertuples():
        d[row[1]][row[2]][row[3]][row[4]].append(row[5])
    d = json.dumps(d)
    d = json.loads(d)

我有这段代码可以读取一些 csv 数据作为数据框。我找到了一种使用 defaultdict 创建树状结构的方法,然后循环遍历 df 并填充它。 数据将始终具有相同的深度 分析器:模式:子模式:文件名:信号

结果如下:

{
  "Analyzer1": {
    "Mode1": { "SubMode1": { "filename2": ["Signal1"] } },
    "Mode2": {
      "SubMode2": {
        "filename1": [
          "Signal2",
          "Signal3"
        ]
      }
    },
    "Mode3": {
      "SubMode1": {
        "filename1": ["Signal2"]
      },
      "SubMode3": {
        "filename1": ["Signal3"]
      }
    }
  },
  "Analyzer2": {
    "Mode1": {
      "SubMode4": {
        "filename1": ["Signal2"]
      }
    }
  }
}

这很好,但我有义务对最终结果进行一些更改,因为此树将与用于显示可折叠菜单的 react 包一起使用(react-checkbox-tree:https://www.npmjs.com/package/react-checkbox-tree

包使用类似的结构,不同之处在于每个级别都有额外的属性,并且它的子级(如果有的话)在一个列表中。这是我想要实现的输出。

[
  {
    "label": "Analyzer1",
    "value": "analyzer1",
    "children": [
      {
        "label": "Mode1",
        "value": "analyzer1/mode1",
        "children": [
          {
            "label": "SubMode1",
            "value": "analyzer1/mode1/submode1",
            "children": [
              {
                "label": "Filename2",
                "value": "analyzer1/mode1/submode1/filename2",
                "children": [
                  {
                    "label": "Signal1",
                    "value": "analyzer1/mode1/submode1/filename2/signal1"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "label": "Mode2",
        "value": "analyzer1/mode2",
        "children": [
          {
            "label": "SubMode2",
            "value": "analyzer1/mode2/submode2",
            "children": [
              {
                "label": "Filename1",
                "value": "analyzer1/mode2/submode2/filename1",
                "children": [
                  {
                    "label": "Signal2",
                    "value": "analyzer1/mode2/submode2/filename1/signal2"
                  },
                  {
                    "label": "Signal3",
                    "value": "analyzer1/mode2/submode2/filename1/signal3"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "label": "Mode3",
        "value": "analyzer1/mode3",
        "children": [
          {
            "label": "SubMode1",
            "value": "analyzer1/mode3/submode1",
            "children": [ 
              {
                "label": "Filename1",
                "value": "analyzer1/mode3/submode1/filename1",
                "children": [
                  {
                    "label": "Signal2",
                    "value": "analyzer1/mode3/submode1/filename1/signal2"
                  }
                ]
              }
            ]
          },
          {
            "label": "SubMode3",
            "value": "analyzer1/mode3/submode3",
            "children": [ 
              {
                "label": "Filename1",
                "value": "analyzer1/mode3/submode3/filename1",
                "children": [
                  {
                    "label": "Signal3",
                    "value": "analyzer1/mode3/submode3/filename1/signal3"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "label": "Analyzer2",
    "value": "analyzer2",
    "children": [
      {
        "label": "Mode1",
        "value": "analyzer2/mode1",
        "children": [
          {
            "label": "SubMode4",
            "value": "analyzer2/mode1/submode4",
            "children": [
              {
                "label": "Filename1",
                "value": "analyzer2/mode1/submode4/filename1",
                "children": [
                  {
                    "label": "Signal2",
                    "value": "analyzer2/mode1/submode4/filename1/signal2"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

我尝试了以下方法,但不完整,我找不到将子节点添加到父节点的方法。

def adjust(d, res, parent, children, path):
        for k, v in d.items():
            if(not isinstance(v, list)):
                path = path + k.lower() + '/'
                parent['value'] = k.lower()
                parent['label'] = k
                adjust(v, res, parent['children'][0], path)
            else:
                parent['children'] = []
            res.append(parent)
adjust(d, [], {}, [], '')

任何建议或指针将不胜感激,我不是很擅长递归。

【问题讨论】:

  • 示例输入和所需输出似乎无关。因此不清楚什么映射到什么。
  • 好的,我重写输出,谢谢
  • 完成@trincot,希望现在很清楚,我的错。

标签: python json pandas tree


【解决方案1】:

你的递归函数不应该有那么多参数。让它自主构建它的子树,只需要路径作为来自调用者的额外信息。并使其功能化,以便它返回它处理的子树的结果。这样调用者就可以将结果注入到它自己的children 属性中。

这是如何工作的:

def maketree(d, path=""):
    if isinstance(d, list):
        return [{ 
            "label": k,
            "value": path + k.lower()
        } for k in d]
    else:
        return [{
            "label": k,
            "value": path + k.lower(),
            "children": maketree(v, path + k.lower() + "/")
        } for k, v in d.items()]

称它为:

tree = maketree(d)

【讨论】:

    猜你喜欢
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多