来自csv python的分层JSON

来自csv python的分层JSON,python,json,csv,hierarchy,Python,Json,Csv,Hierarchy,我有一个csv格式的数据集,如下所示: Name,code,count Adam,01,48 Bill,01,32 Chris,01,4 Carl,01.01,5 Dave,01.01,1 David,01.01,1 Eric,01.01.01,26 Earl,01.01.01.01,2 Frank,01.01.01.01,2 Greg,01.01.01.02,2 Harold,01.01.01.03,7 Ian,01.01.01.03,3 Jack,01.01.01.03,1 John,01.

我有一个csv格式的数据集,如下所示:

Name,code,count
Adam,01,48
Bill,01,32
Chris,01,4
Carl,01.01,5
Dave,01.01,1
David,01.01,1
Eric,01.01.01,26
Earl,01.01.01.01,2
Frank,01.01.01.01,2
Greg,01.01.01.02,2
Harold,01.01.01.03,7
Ian,01.01.01.03,3
Jack,01.01.01.03,1
John,01.01.01.04,10
Kyle,01.01.01.04,2
Larry,01.01.03.01,3
Mike,01.01.03.01.01,45
Nick,01.01.03.01.01.01,1
Oliver,01.01.03.01.01.02,16
Paul,01.01.03.01.01.03,23

我想用python制作一个字典,其中“name”和“count”是键:值对(这很简单),但我想根据“code”编号组织一个层次结构。i、 e 01.01是01的孩子,我不确定如何迭代数据以实现这一点。我最终想对整个结构进行json转储,但让我失望的是如何构造层次结构。非常感谢您的帮助。

我想您应该做一些标准的树结构,您可以访问树结构,使用路径访问时会自动创建缺少的节点

像这样的

class Node:
    def __init__( self, parent=None ):
        self.parent = parent
        self.store = {}
        self.children = {}

    def create_child( self, child_name ):
        self.children[ child_name ] = Node( self )

    #ancestry_line is a list of names
    def recursive_get_child( self, ancestry_line_names ):
        if len(ancestry_line_names) == 0:
            return self
        else:
            next_ancestor = ancestry_line_names[0]
            other_ancestors = ancestry_line_names[1:]
            if next_ancestor not in self.children:
                self.create_child( next_ancestor )
            return self.children[ next_ancestor ].recursive_get_child( other_ancestors )
您所需要做的就是创建一个根节点,并通过路径从中访问正确的节点

root = Node()
for name, code, count in some_data_iterator():
    ancestry_line = code.split(".")
    root.get( ancestry_line ).store[ name ] = count

然后,您可以在
节点
中创建一个方法,将节点结构转换为可在
json
中转储的纯字典结构。下面的代码片段查找树的所有节点,而不实际创建一个。Python中的树和链表实现效率低下(Beazley)


在Python中实现树结构的一种简单而优雅的方法是使用递归:


您能否提供所需输出的示例?开始时有三个
01
元素-
01.01
元素应如何适应层次结构?要将其分配给哪个元素?能否显示“层次结构”的一个片段。csv的某些行上最多显示5个其他字段?谢谢C Panda!这很有效。你能编辑你的回复,把这些行放进:import csv f=open(“somefile.csv”,“r”)……我想有些人需要them@miltonjbradley哪行bdw?我喜欢干净的代码。但是,它并没有使树结构显式化。@schwobasegll我知道这一点。因为我不知道继承人的样子。我不能给结果dict键赋予任何语义。我的python树将始终是一个
dict
。但是我想知道它是什么样子。@CPanda我想如果你从内部的
dicts
中删除多余的
code
,只使用
name:count
键值对,它会更干净。这将使结果在不丢失信息的情况下更不冗长。感谢您的回复。这只适用于一小部分人。我一使用整个文件,就出现了一个“太大而无法解包”的错误
from itertools import groupby
import csv

with open('csvfile.csv') as f:
    reader = csv.DictReader(f)

groups = groupby(reader, key=lambda row: row['code'])
nodes = {code: {item['Name']: item['count'] for item in group} for code,group in groups}

{'01': {'Adam': '48', 'Bill': '32', 'Chris': '4'},
 '01.01': {'Carl': '5', 'Dave': '1', 'David': '1'},
 '01.01.01': {'Eric': '26'},
 '01.01.01.01': {'Earl': '2', 'Frank': '2'},
 '01.01.01.02': {'Greg': '2'},
 '01.01.01.03': {'Harold': '7', 'Ian': '3', 'Jack': '1'},
 '01.01.01.04': {'John': '10', 'Kyle': '2'},
 '01.01.03.01': {'Larry': '3'},
 '01.01.03.01.01': {'Mike': '45'},
 '01.01.03.01.01.01': {'Nick': '1'},
 '01.01.03.01.01.02': {'Oliver': '16'},
 '01.01.03.01.01.03': {'Paul': '23'}}
import csv, json
from collections import defaultdict

def tree():
    return defaultdict(tree)

d = tree()

with open('data.txt', 'rb') as f:
    reader = csv.reader(f, delimiter=',')

    for name, code, count in list(reader)[1:]:
        path = code.split('.')
        iter_node = d
        for node in path:
            iter_node = iter_node[node]
        iter_node['values'][name] = count

print json.dumps(d, indent=2)

{
  "01": {
    "values": {
      "Chris": "4", 
      "Bill": "32", 
      "Adam": "48"
    },
    "01": {
      "values": {
        "Dave": "1", 
        "Carl": "5", 
        "David": "1"
      },
      "03": {
        "01": {
          "01": {
            "02": {
              "values": {
                "Oliver": "16"
              }
            }, 
            "03": {
              "values": {
                "Paul": "23"
              }
            }, 
            "01": {
              "values": {
                "Nick": "1"
              }
            }, 
            "values": {
              "Mike": "45"
            }
          }, 
          "values": {
            "Larry": "3"
          }
        }
      }, 
      "01": { 
        "values": {
          "Eric": "26"
        }, 
        "02": {
          "values": {
            "Greg": "2"
          }
        }, 
        "03": {
          "values": {
            "Harold": "7", 
            "Ian": "3", 
            "Jack": "1"
          }
        }, 
        "01": {
          "values": {
            "Earl": "2", 
            "Frank": "2"
          }
        },
        "04": {
          "values": {
            "John": "10", 
            "Kyle": "2"
          }
        }
      }
    }
  }
}