2016-05-16 60 views
1

我有一個在CSV結構這樣的數據集:層次JSON

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裏的「名」和「計數」是關鍵:值對(這很容易),但我想組織一個基於「代碼」編號的層次結構。即01.01是01的孩子,我不知道如何迭代數據來實現這一點。我最終希望做一個整體結構的JSON轉儲,但是它是如何構造讓我失望的層次結構。任何幫助是極大的讚賞。

+0

你能提供所需的輸出的例子嗎?你在開始時有三個'01'元素 - 01.01'元素應該如何適應層次結構?要分配給哪個元素? – iulian

+0

您可以顯示「層級」的外觀片段嗎? –

+0

csv某些行上最多顯示5個其他字段是什麼? – martineau

回答

1

在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" 
      } 
     } 
     } 
    } 
    } 
} 
0

我想你想要做一些標準的樹結構,在那裏你可以訪問一個樹結構,缺少節點時自動創建一個路徑訪問。

就是這樣。

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創建一個方法與節點結構轉換爲可用在json轉儲純字典結構。

+0

感謝您的回覆。這適用於一個小列表。只要我使用整個文件,我得到了「太大而無法解壓」錯誤 – miltonjbradley

1

下面的代碼片段找到了一棵樹的所有節點,但實際上並沒有創建它。 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'}} 
+0

感謝C熊貓!這很好。你可以編輯你的迴應把這些行:import csv f = open(「somefile.csv」,「r」).....我想有些人會需要他們 – miltonjbradley

+0

@miltonjbradley哪行bdw? –

+0

我喜歡乾淨的代碼。但是,它不會使樹結構顯式化。 – schwobaseggl