Конвертировать CSV в древовидную структуру JSON и изменить имя? - PullRequest
0 голосов
/ 05 июня 2018

Спасибо Хэтту за объяснение и код.Это работает, хотя я не могу изменить строку name для значимого имени из заголовков столбцов.

Кто-нибудь может подсказать, как этого добиться?

Данные в CSV-файле

conversion_month    channel sub_channel campaign    Id  cost    kpi
2017-08 DISPLAY Retargeting Summer_Campaign 200278217   2.286261    0.1
2017-08 DISPLAY Retargeting Summer_Campaign 200278218   3.627064    2.5
2017-08 DISPLAY Retargeting Summer_Campaign 200278219   2.768436    0.001
2017-08 DISPLAY Retargeting August Campaign 200278220   5.653297    0.35
2017-09 DISPLAY Prospecting Test Campaign   200278221   4.11847 1.5
2017-08 DISPLAY Prospecting August Campaign 200278222   3.393972    0.26
2017-09 DISPLAY Prospecting Test Campaign   200278223   3.975332    4.2
2017-08 DISPLAY Prospecting August Campaign 200278224   4.131035    0.3

Используемый код:

import csv
from collections import defaultdict

def ctree():
    return defaultdict(ctree)

def build_leaf(name, leaf):
    res = {"name":name}
    # add children node if the leaf actually has any children
    if len(leaf.keys()) > 0:
        res["children"] = [build_leaf(k, v) for k, v in leaf.items()]
    return res

def main():
    tree = ctree()
    with open('file.csv') as csvfile:
        reader = csv.reader(csvfile)
        for rid, row in enumerate(reader):
            if rid == 0:       
                continue
            leaf = tree[row[0]]
            for cid in range(1, (len(row)-2)):
                leaf = leaf[row[cid]]
            for cid in range((len(row)-1), len(row)):
                leaf = (leaf[row[cid-1]],leaf[row[cid]])
    # building a custom tree structure
    res = []
    for name, leaf in tree.items():
        res.append(build_leaf(name, leaf))

    # printing results into the terminal
    import json
    print(json.dumps(res, indent=2))

main()

Это дает дерево,но я хотел бы изменить строку "имя" для значащего имени, такого как "месяц", "канал", ... "идентификатор" и т. д. Имена находятся в первой строке файла CSV.

[
  {
    "name": "2017-08",
    "children": [
      {
        "name": "DISPLAY",
        "children": [
          {
            "name": "Retargeting",
            "children": [
              {
                "name": "Summer_Campaign",
                "children": [
                  {
                    "name": "200278217",
                    "children": [
                      {
                        "name": "2.286261"
                      },
                      {
                        "name": "0.1"
                      }
                    ]

Спасибо за любые предложения заранее.

1 Ответ

0 голосов
/ 06 июня 2018

Используйте next(reader), чтобы сначала извлечь строку заголовка из файла CSV.Счетчик level может использоваться для указания того, с каким столбцом в данный момент ведется работа, поэтому из заголовка можно извлечь соответствующий заголовок столбца:

import csv
from collections import defaultdict

def ctree():
    return defaultdict(ctree)

def build_leaf(name, leaf, level, header):
    res = {header[level] : name}
    # add children node if the leaf actually has any children
    if len(leaf.keys()) > 0:
        res["children"] = [build_leaf(k, v, level+1, header) for k, v in leaf.items()]
    return res

def main():
    tree = ctree()
    with open('file.csv') as csvfile:
        reader = csv.reader(csvfile)
        header = next(reader)

        for row in reader:
            leaf = tree[row[0]]
            for cid in range(1, (len(row)-2)):
                leaf = leaf[row[cid]]
            for cid in range((len(row)-1), len(row)):
                leaf = (leaf[row[cid-1]],leaf[row[cid]])

    # building a custom tree structure
    res = []
    for name, leaf in tree.items():
        res.append(build_leaf(name, leaf, 0, header))

    # printing results into the terminal
    import json
    print(json.dumps(res, indent=2))

main()

Это даст вам:

[
  {
    "conversion_month": "2017-08",
    "children": [
      {
        "channel": "DISPLAY",
        "children": [
          {
            "sub_channel": "Retargeting",
            "children": [
              {
                "campaign": "Summer_Campaign",
                "children": [
                  {
                    "Id": "200278217",
                    "children": [
                      {
                        "cost": "2.286261"
                      },
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...