将csv转换为JSON树结构?

时间:2017-05-03 10:51:39

标签: python json csv d3.js tree

我读了这些问题:

但是我仍然无法将csv文件转换为JSON的层次结构。我在stackoverflow上找到的脚本特定于某个问题。让我们说有三个变量需要分组:

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之类的结构。

1 个答案:

答案 0 :(得分:10)

使用defaultdict标准库中的collections会使层次结构容易且可解决的问题变得很多。所以我为您的问题开发了一个示例解决方案。但是在运行脚本之前,请确保使用逗号分隔的csv文件(名为test.csv),或者可以在那里更改csv reader逻辑。

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

<h2>Hello [[prop1]]!</h2>

从技术上讲,该脚本应适用于任何类型的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

以下是结果中的json片段:

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()

如果您有任何其他问题和疑问,请与我们联系。 快乐的pythonning;)