来自 csv python 的分层 JSON
Hierarchical JSON from csv python
我有一个以 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" 是 key:value 对(这很容易),但我想整理基于 "code" 数字的层次结构。即 01.01 是 01 的 child,我不确定如何遍历数据来实现这一点。我最终想对整个结构进行 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
然后您可以在 Node
中创建一个方法,将 Node 结构转换为可用于在 json
中转储的纯字典结构。
下面的代码片段找到了一棵树的所有节点,而不是实际创建一个节点。 Python 中的树和链表实现效率低下 (Beazley)。
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'}}
在 Python 中实现树结构的一种简单而优雅的方法使用递归 defaultdict
:
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"
}
}
}
}
}
}
我有一个以 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" 是 key:value 对(这很容易),但我想整理基于 "code" 数字的层次结构。即 01.01 是 01 的 child,我不确定如何遍历数据来实现这一点。我最终想对整个结构进行 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
然后您可以在 Node
中创建一个方法,将 Node 结构转换为可用于在 json
中转储的纯字典结构。
下面的代码片段找到了一棵树的所有节点,而不是实际创建一个节点。 Python 中的树和链表实现效率低下 (Beazley)。
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'}}
在 Python 中实现树结构的一种简单而优雅的方法使用递归 defaultdict
:
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"
}
}
}
}
}
}