2016-08-23 101 views
1

我想將許多JSON文件寫入CSV文件。每個JSON文件都有幾個鍵,但不同的文件有不同的鍵。以三個JSON文件爲例。在python中將JSON轉換爲CSV:每個JSON文件都有不同的鍵

文件答:

{"a": 1, "c": 2} 

文件B:

{"b": 5, "d": 3} 

文件C:

{"a": 6, "b": 7} 

我想是這樣一個CSV文件具有四個列三行(爲簡單起見省略逗號):

a b c d 

1 2 

    5 3 

6 7 

做到這一點的一種方法是通過使用csv編寫器的多個try/except語句。但是當我處理大量密鑰時,這變得不可行。有沒有其他的選擇?

+0

並沒有真正像CSV,使用空格作爲分隔符和「空的空間」會使加載數據真的很困難。您是否也提前知道所有可能的鑰匙? –

+0

你應該顯示你的代碼。 –

回答

2

您可以將每個JSON文件附加到列表中,然後創建數據框和連接。

a = {"a": 1, "c": 2} 
b = {"b": 5, "d": 3} 
c = {"a": 6, "b": 7} 
data = [a, b, c] 

>>> pd.concat([pd.DataFrame(s, index=[0]) for s in data]).reset_index() 
    a b c d 
0 1 NaN 2 NaN 
1 NaN 5 NaN 3 
2 6 7 NaN NaN 
2

您可以使用缺少的關鍵字加載每個單獨的字典並將它們賦予空值。因此,它可能看起來像這樣

for items in list: 
    for x in ['a','b','c','d']: 
     if x not in item: 
      item[x] = "" 

現在每個字典具有相同的鑰匙,你應該能夠很容易地寫在CSV文件所需的格式。

+1

1:這就是'dict.setdefault'的意圖,2:a ['defaultdict'](https://docs.python.org/3/library/collections.html#collections.defaultdict)可以做到這一點更有效率。 –

3

假設你的時間提前csv.DictWriter已經自帶了一個解決方案瞭解所有可能的字段名稱,使用restval參數的構造函數:

如果行讀取比更少的字段字段名稱序列, 其餘鍵取可選參數restval的值。

因此指定csv.DictWriter(..., restval=" ")將與這或許會對你更有用反正一個單一的空間,雖然在默認情況下restval設置爲""(空字符串)更換任何缺失值。

所以基本上你的代碼應該是這樣的:

import csv, json 
all_fields = ["a","b","c","d"] 
all_files = ["A.json","B.json","C.json"] 

with open("OUTPUT.csv", "w") as output_file: 
    writer = csv.DictWriter(output_file,all_fields) 
    writer.writeheader() 

    for filename in all_files: 
     with open(filename,"r") as in_file: 
      writer.writerow(json.load(in_file)) 
0

這工作:

csv_separator = ';' 

data = [{"a": 1, "c": 2}, 
{"b": 5, "d": 3}, 
{"a": 6, "b": 7}] 

headers = sorted(list(set(sum([list(l.keys()) for l in data], [])))) 

with open('output.csv', 'w+') as f: 
    f.write(csv_separator.join(headers)) 
    for l in data: 
     line_elements = [] 
     for k in headers: 
      try: 
       line_elements.append(str(l[k])) 
      except: # key not in dict, append empty string, i'll let you catch the exception properly 
       line_elements.append('') 
     f.write(csv_separator.join(line_elements)) 


# Output : 
# a;b;c;d 
# 1;;2; 
# ;5;;3 
# 6;7;; 
+0

爲什麼你打印一個文件,如果打印一切到標準輸出?你也可以在字典上使用'.get'方法來處理丟失的鍵。 –

+0

我忘了寫入文件,只是管輸出,謝謝你的關注。 –