将csv转换为嵌套的json树结构?

时间:2019-09-16 06:41:02

标签: python json csv

我有如下data.csv,我打算使用它来为d3js太阳爆发可视化创建json:

REGION_CODE,LOCATION_CODE,SKU_CODE,BASIC_SALES
Region 0,Location 10,SKU 500118,25
Region 0,Location 10,SKU 500122,34
Region 0,Location 11,SKU 500123,34
Region 0,Location 11,SKU 500124,68

我正尝试将其转换为嵌套的json,如下所示:

{
    'name': 'region 0',
    'shortName': 'region 0',
    'children': [
        {
            'name': 'location 10',
            'shortName': 'location 10',
            'children':[
                {
                    'name': 'SKU 500118',
                    'shortName': 'SKU 500118',
                    'size': '25'
                }, 
                {
                    'name': 'SKU 500122',
                    'shortName': 'SKU 500122',
                    'size': '34'
                }
            ]
        },
        {
            'name': 'location 11',
            'shortName': 'location 11',
            'children': [
                {
                    'name': 'SKU 500123',
                    'shortName': 'SKU 500123',
                    'size': '34'
                },
                {
                    'name': 'SKU 500124',
                    'shortName': 'SKU 500124',
                    'size': '68'
                }
            ]
        }
    ]
}

我在Stackoverflow上发现了几乎类似的解决方案,convert-csv-to-json-tree-structure,但它一直处理到最后一行并将其添加为子级,而我希望将倒数第二行添加为子级并将最后一行添加为子级如上所示添加为大小。

1 个答案:

答案 0 :(得分:1)

我查看了类似的示例,并根据您的要求对其进行了修改。

脚本假定任何元组只有一个BASIC_SALES号 (REGION_CODE,LOCATION_CODE,SKU_CODE)

import csv
import json

# helper to create dict of dict of .. of values
def add_leaf(tree, row):
    key = row[0]
    if len(row) > 2:
        if not key in tree:
            tree[key] = {}
        add_leaf(tree[key], row[1:])
    if len(row) == 2:
            tree[key] = row[-1]

# transforms helper structure to final structure
def transform_tree(tree):
    res = []
    res_entry = []
    for key, val in tree.items():
        if isinstance(val, dict):
            res.append({
                "name": key,
                "shortName": key,
                "children": transform_tree(val),
                })
        else:
            res.append({
                "name": key,
                "shortName": key,
                "size": val,
                })
    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.
    It uses the recursive function add_leaf for it.

    Second it's recursively transforms this tree structure into the
    desired hierarchy

    And the last part is just printing the result.

    """

    # Part1 create a hierarchival dict of dicts of dicts.
    # The leaf cells are however just the last element of each row
    tree = {}
    with open('test.csv') as csvfile:
        reader = csv.reader(csvfile)
        for rid, row in enumerate(reader):
            if rid == 0:  # skip header row
                continue
            add_leaf(tree, row)

    # uncomment to visualize the intermediate result
    # print(json.dumps(tree, indent=1))
    # print("=" * 76)

    # transfor the tree into the desired structure
    res = transform_tree(tree)
    print(json.dumps(res, indent=1))

# so let's roll
main()