将 csv 转换为 JSON 树结构?

Posted

技术标签:

【中文标题】将 csv 转换为 JSON 树结构?【英文标题】:Convert csv to JSON tree structure? 【发布时间】:2017-10-01 03:53:49 【问题描述】:

我阅读了这些问题:

csv data to nested json tree in d3 Create a json tree from csv list in python How to Create a JSON Tree from a Tabulated Hierarchy in Python Python csv to nested JSON [closed]

但是我仍然无法将 csv 文件转换为 JSON 的层次结构。我在 *** 上找到的所有脚本都是针对某个问题的。假设必须对三个变量进行分组:

condition   target  sub
oxygen      tree    G1
oxygen      tree    G2
water       car     G3
water       tree    GZ
fire        car     GTD
oxygen      bomb    GYYS

这将产生一个像这样的 JSON 文件(据我尝试):

oxygen
    - tree  
        - G1
        - G2
    - bomb
        -GYYS
water 
    - car
        - G3
    - tree
        -GZ
fire 
    - car   
        - GTD

这些必须分组在一个嵌套结构中,例如:

    
   "name": "oxygen",
   "children": [
    
     "name": "tree",
     "children": [
      "name": "G1",
      "name": "G2",
      "name": "GYYS"
     ]
    ,
    
     "name": "bomb",
      "children": [
      "name": "GYYS"
     ]
    
    ]

etc.

我尝试了这个站点上的每个脚本,但是我无法制作一个可以制作这样一个flare.json 的通用函数。我可以发布我的代码,但这就像上面提供的链接一样。因此,我要求提供一个简单的代码(或可以帮助我的示例)将其转换为类似flare.JSON 的结构。

【问题讨论】:

您的“三个变量”没有出现在您的json示例中的任何地方,没有明显的联系。所以请详细说明如何从csv文件中的数据生成json结构 我对 JSON 不太熟悉,但我试着举一个简短的例子来说明我想要什么(见编辑)@ChristianKönig 能否请您将您的 json 示例复制并粘贴到 jsoneditoronline.org 此查看器/验证器中,并至少为我们提供有效的 json 示例,因为您的 json 示例不是有效的 json。还请提供规则(高级逻辑)如何将 csv 转换为 json,什么变成了孩子,为什么?这些信息将有助于为您提供有效的答案。 感谢在线编辑器我现在修复了我的 JSON @Hett @CodeNoob 我认为您提供了错误的 JSON。从 csv 我猜 tree 的孩子应该是 [G1, G2] 并且 [GYYS] 应该只作为炸弹的孩子呈现。我对吗?你需要正确解释层级逻辑(因为只有你知道你需要什么)。 【参考方案1】:

使用collections 标准库中的defaultdict 可以轻松解决许多层次结构问题。因此,我为您的问题开发了一个示例解决方案。但在运行脚本之前,请确保您有逗号分隔的 csv 文件(名为 test.csv),或者您可以在下面更改 csv reader 逻辑。

这是我测试过脚本的 csv 文件。

condition, target, sub, dub
oxygen,tree,G1,T1
oxygen,tree,G2,T1
oxygen,tree,G2,T2
water,car,G3,T1
water,tree,GZ,T1
water,tree,GZ,T2
fire,car,GTD,T3
oxygen,bomb,GYYS,T1

从技术上讲,该脚本应该适用于具有各种尺寸的任何类型的 csv 文件。但是你需要自己测试才能确定。

import csv
from collections import defaultdict


def ctree():
    """ One of the python gems. Making possible to have dynamic tree structure.

    """
    return defaultdict(ctree)


def build_leaf(name, leaf):
    """ Recursive function to build desired custom tree structure

    """
    res = "name": name

    # add children node if the leaf actually has any children
    if len(leaf.keys()) > 0:
        res["children"] = [build_leaf(k, v) for k, v in leaf.items()]

    return res


def main():
    """ The main thread composed from two parts.

    First it's parsing the csv file and builds a tree hierarchy from it.
    Second it's recursively iterating over the tree and building custom
    json-like structure (via dict).

    And the last part is just printing the result.

    """
    tree = ctree()
    # NOTE: you need to have test.csv file as neighbor to this file
    with open('test.csv') as csvfile:
        reader = csv.reader(csvfile)
        for rid, row in enumerate(reader):

            # skipping first header row. remove this logic if your csv is
            # headerless
            if rid == 0:
                continue

            # usage of python magic to construct dynamic tree structure and
            # basically grouping csv values under their parents
            leaf = tree[row[0]]
            for cid in range(1, len(row)):
                leaf = leaf[row[cid]]

    # building a custom tree structure
    res = []
    for name, leaf in tree.items():
        res.append(build_leaf(name, leaf))

    # printing results into the terminal
    import json
    print(json.dumps(res))


# so let's roll
main()

这是结果中的 json 片段:


    "name": "oxygen",
    "children": [
      
        "name": "tree",
        "children": [
          
            "name": "G2",
            "children": [
              
                "name": "T2"
              ,
              
                "name": "T1"
              
            ]
          ,
          
            "name": "G1",
            "children": [
              
                "name": "T1"
              
            ]
          
        ]
      ,
      
        "name": "bomb",
        "children": [
          
            "name": "GYYS",
            "children": [
              
                "name": "T1"
              
            ]
          
        ]
      
    ]
  

如果您有任何其他问题和问题,请告诉我。 快乐的蟒蛇;)

【讨论】:

非常感谢!与堆栈上的所有其他答案一样容易理解 很高兴这有帮助! @Hett 如果我在 csv 文件中有 URL 怎么办?我的意思是,我有 URL 源和 URL 目标,我想根据 URL 中的目录创建一个树,并绘制一个像这样的图形bl.ocks.org/mbostock/1062288 任何想法?【参考方案2】:

另一种解决方案,使用convtools 代码生成库:

from convtools import conversion as c
from convtools.contrib.tables import Table


table = Table.from_csv(
    "tmp2.csv", header=True, dialect=Table.csv_dialect(delimiter="\t")
)

child = None
for column in reversed(table.columns):
    if child is None:
        # the most inner children
        child = c.iter(c.item(column)).as_type(list)
    else:
        child = c.group_by(c.item(column)).aggregate(
            
                "name": c.item(column),
                "children": c.ReduceFuncs.Array(c.this()).pipe(child),
            
        )
# this is where code generation happens
converter = child.gen_converter()

converter(table.into_iter_rows(dict))

输出:

[
    
        "name": "oxygen",
        "children": [
            "name": "tree", "children": ["G1", "G2"],
            "name": "bomb", "children": ["GYYS"],
        ],
    ,
    
        "name": "water",
        "children": [
            "name": "car", "children": ["G3"],
            "name": "tree", "children": ["GZ"],
        ],
    ,
    "name": "fire", "children": ["name": "car", "children": ["GTD"]],
]

【讨论】:

以上是关于将 csv 转换为 JSON 树结构?的主要内容,如果未能解决你的问题,请参考以下文章

怎样将树结构数据组织成json数据,页面通过jquery.tree.js解析json来展现树,求大体思路

JS,实现一维数组JSON树结构的转换

如何将此树结构转换为 JS MemberExpression 树结构?

将扁平的分层数据转换为树状结构的 JSON

强制 Chrome 显示格式为树结构的 Json 响应

将数据框转换为列表的树结构列表