2016-09-14 2 views
1

У меня есть несколько файлов, каждый из которых содержит несколько сильно вложенных json строк. Два первых ряда одного из таких файлов выглядят так:Несколько jsons to csv

{ 
"u":"28", 
"evv":{ 
     "w":{ 
      "1":400, 
      "2":{ 
       "i":[{ 
         "l":14, 
         "c":"7", 
         "p":"4" 
         } 
        ] 
       } 
      } 
     } 
} 
{ 
"u":"29", 
"evv":{ 
     "w":{ 
      "3":400, 
      "2":{ 
       "i":[{ 
         "c":14, 
         "y":"7", 
         "z":"4" 
         } 
        ] 
       } 
      } 
     } 
} 

они фактически являются строками, я просто написал их здесь таким образом, чтобы получить дополнительную видимость.

Мой вопрос заключается в следующем:

Есть ли способ, чтобы преобразовать все эти файлы в один (или несколько, то есть по одному на файл) CSV/Excel ...?

Есть ли простой способ, который не требует написания десятки или сотни строк в Python, специфичные для моего файла, чтобы преобразовать все эти файлы в один (или несколько, то есть по одному на файл) в формате CSV/excel ...? В качестве примера можно использовать внешнюю библиотеку, скрипт ..., который обрабатывает эту конкретную задачу независимо от имен полей.

Ловушка заключается в том, что некоторые элементы не отображаются в каждой строке. Например, для ключа «i» мы имеем 3 поля (l, c, p) в первом json и 3 во втором (c, y, z). В идеале, csv должен содержать как можно больше столбцов (например, evv.w.2.il, evv.w.2.ic, evv.w.2.ip, evv.w.2.iy, evv.w. 2.iz), рискуя иметь (много) нулевых значений в строке csv.

Возможный выход CSV для этого примера будет иметь следующие столбцы:

u, evv.w.1, evv.w.3, evv.w.2.i.l, evv.w.2.i.c, evv.w.2.i.p, evv.w.2.i.y, evv.w.2.i.z 

Любая идея/ссылка на приветствуется :)

Благодаря

+0

Да, это возможно - я рекомендую смотреть на Питона [JSON] (https://docs.python.org/2/library/json.html) и [CSV] (https://docs.python.org/2/library/csv.html) и пытается написать скрипт, который делает то, что вы хотите. Вернитесь сюда, если вы застряли, и мы поможем вам отладить вашу программу –

+0

Пожалуйста, отредактируйте свой вопрос и покажите, что должен содержать файл csv для данных примера и код, который вы написали, чтобы попытаться сделать это самостоятельно. – martineau

+0

@HaydenSchiff, я знаю о существовании этих двух модулей и Я знаю, что могу использовать их для xactly, что я хочу, хотя это может быть очень громоздким. Мой вопрос заключается в том, написан ли скрипт, который делает то, что я хочу, до – Salem

ответ

1

Нет, нет общего назначения программы, которая делает именно то, что вы просите.

Вы можете, однако, написать программу Python, которая это делает.

Эта программа может делать то, что вы хотите. Он не имеет никакого кода, специфичного для ваших имен ключей, но он специфичен для вашего формата файла.

  • Это может занять несколько файлов в командной строке.
  • Каждый файл, как предполагается, имеет один объект JSON в строке.
  • Он сглаживает объект JSON, соединяя метки с символом "."

 

import fileinput 
import json 
import csv 


def flattify(d, key=()): 
    if isinstance(d, list): 
     result = {} 
     for i in d: 
      result.update(flattify(i, key)) 
     return result 
    if isinstance(d, dict): 
     result = {} 
     for k, v in d.items(): 
      result.update(flattify(v, key + (k,))) 
     return result 
    return {key: d} 

total = [] 
for line in fileinput.input(): 
    if(line.strip()): 
     line = json.loads(line) 
     line = flattify(line) 
     line = {'.'.join(k): v for k, v in line.items()} 
     total.append(line) 

keys = set() 
for d in total: 
    keys.update(d) 

with open('result.csv', 'w') as output_file: 
    output_file = csv.DictWriter(output_file, sorted(keys)) 
    output_file.writeheader() 
    output_file.writerows(total) 
+0

Amazing, thanks :) Я не думаю, что это обрабатывает несколько записей в списке внутри json (пример evv.w.2.i. Один из способов сделать это - создать столько столбцов, сколько необходимо, например: ' Если isinstance (d, list): d = {str (i): j для i, j в перечислении (d)} return flattify (d, key = key) ' – Salem

1

Пожалуйста, проверьте, если это (Python3) решение работает для тебя.

import json 
import csv 

with open('test.json') as data_file: 
    with open('output.csv', 'w', newline='') as fp: 
     for line in data_file: 
      data = json.loads(line) 
      output = [[data['u'], data['evv']['w'].get('1'), data['evv']['w'].get('3'), 
         data['evv']['w'].get('2')['i'][0].get('l'), data['evv']['w'].get('2')['i'][0].get('c'), 
         data['evv']['w'].get('2')['i'][0].get('p'), data['evv']['w'].get('2')['i'][0].get('y'), 
         data['evv']['w'].get('2')['i'][0].get('z')]] 
      a = csv.writer(fp, delimiter=',') 
      a.writerows(output) 

test.json

{ "u": "28", "evv": {  "w": {   "1": 400,   "2": {    "i": [{     "l": 14,     "c": "7",     "p": "4"    }]   }  } }} 
{"u":"29","evv":{  "w":{   "3":400,   "2":{     "i":[{      "c":14,      "y":"7",      "z":"4"      }      ]     }   }  }} 

выхода

python3 pyprog.py 
[email protected] ~/P/pyprog> more output.csv 
28,400,,14,7,4,, 
29,,400,,14,,7,4