Создать вложенный JSON из плоского CSV - PullRequest
2 голосов
/ 31 октября 2011

Попытка создать 4 глубоко вложенных JSON из CSV на основе этого примера:

Region,Company,Department,Expense,Cost
Gondwanaland,Bobs Bits,Operations,nuts,332
Gondwanaland,Bobs Bits,Operations,bolts,254
Gondwanaland,Maureens Melons,Operations,nuts,123

На каждом уровне я хотел бы суммировать затраты и включить их в выводимый JSON на соответствующем уровне.

Структура выведенного JSON должна выглядеть примерно так:

    {
          "id": "aUniqueIdentifier", 
          "name": "usually a nodes name", 
          "data": [
                {
                      "key": "some key", 
                      "value": "some value"
                }, 
                {
                      "key": "some other key", 
                      "value": "some other value"
                }
          ], 
          "children": [/* other nodes or empty */ ]
    }

(REF: http://blog.thejit.org/2008/04/27/feeding-json-tree-structures-to-the-jit/)

Думая в русле рекурсивной функции в python, но пока не достиг большого успеха в этом подходе ... любые предложения по быстрому и простому решению очень приветствуются?

UPDATE: Постепенно разочаровываюсь в идее суммированных затрат, потому что я просто не могу понять :(. Я пока не сильно разбираюсь в python-кодере)! Достаточно было бы просто сгенерировать отформатированный JSON, и я могу добавить цифры позже, если потребуется.

Читал, гуглял и читал для решения и в пути многому научился, но до сих пор не достиг успеха в создании моих вложенных файлов JSON из вышеупомянутой структуры CSV. Должно ли быть простым решением где-то в Интернете? Может быть, кому-то больше повезло с их поисковыми терминами ????

1 Ответ

8 голосов
/ 31 октября 2011

Вот несколько советов.

Разобрать ввод в список списков с помощью csv.reader :

>>> rows = list(csv.reader(source.splitlines()))

Прокрутите список, чтобы построить свой словарь и суммировать затраты. В зависимости от структуры, которую вы хотите создать, сборка может выглядеть примерно так:

>>> summary = []
>>> for region, company, department, expense, cost in rows[1:]:
    summary.setdefault(*region, company, department), []).append((expense, cost))

Запишите результат с помощью json.dump :

>>> json.dump(summary, open('dest.json', 'wb'))

Надеюсь, приведенная ниже рекурсивная функция поможет вам начать работу. Он строит дерево из входных данных. Пожалуйста, знайте, какого типа вы хотите, чтобы ваши листья были, что мы помечаем как «стоимость». Вам нужно будет уточнить эту функцию, чтобы создать точную структуру, которую вы намереваетесь:

import csv, itertools, json

def cluster(rows):
    result = []
    for key, group in itertools.groupby(rows, key=lambda r: r[0]):
        group_rows = [row[1:] for row in group]
        if len(group_rows[0]) == 2:
            result.append({key: dict(group_rows)})
        else:
            result.append({key: cluster(group_rows)})
    return result

if __name__ == '__main__':
    s = '''\
Gondwanaland,Bobs Bits,Operations,nuts,332
Gondwanaland,Bobs Bits,Operations,bolts,254
Gondwanaland,Maureens Melons,Operations,nuts,123
'''
    rows = list(csv.reader(s.splitlines()))
    r = cluster(rows)
    print json.dumps(r, indent=4)
...