从 csv 数据为折叠菜单创建树结构
Create tree structure from csv data for collapse menu
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"]
}
}
}
}
这很好,但我有义务对最终结果做一些更改,因为这棵树将与反应包一起使用以显示可折叠菜单(反应复选框树: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, [], {}, [], '')
任何建议或指示将不胜感激,我不是很擅长做递归。
你的递归函数不应该有那么多参数。让它自主构建其子树,只需要路径作为来自调用者的额外信息。并使其 functional,以便它 returns 它处理的子树的结果。这样调用者就可以将结果注入到它自己的 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)
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"]
}
}
}
}
这很好,但我有义务对最终结果做一些更改,因为这棵树将与反应包一起使用以显示可折叠菜单(反应复选框树: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, [], {}, [], '')
任何建议或指示将不胜感激,我不是很擅长做递归。
你的递归函数不应该有那么多参数。让它自主构建其子树,只需要路径作为来自调用者的额外信息。并使其 functional,以便它 returns 它处理的子树的结果。这样调用者就可以将结果注入到它自己的 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)