Python — фрейм данных pandas во вложенный json с уровнем иерархии

Чтобы иметь возможность генерировать флажки, мне нужно преобразовать pandas DataFrame в формат JSON.

Во-первых, у меня есть фрейм данных pandas:

В роляхзаглавиетип
Дэниел КрейгПадение небаФильм
Ахмед БакареПлохие привычкиКлип
Леонардо ДикаприоТитаникФильм
Джуди ДенчПадение небаФильм
Кейт УинслетТитаникФильм
Эмили РатаковскиРазмытые линииКлип
Эль ЭвансРазмытые линииКлип

Я хотел бы преобразовать его так же, как формат ниже:

{
 "Movie": {
    "label": "Movie",
    "children": {
      "Sky Fall": {
        "label": "Sky Fall",
        "children": {
          "Daniel Craig": {
            "label": "Daniel Craig"
          },
          "Judi Dench": {
            "label": "Judi Dench"
          }
        }
      },
      "Titanic": {
        "label": "Titanic",
        "children": {
          "Leonardo Dicaprio": {
            "label": "Leonardo Dicaprio"
          },
          "Kate Winslet": {
            "label": "Kate Winslet"
          }
        }
      }
    }
  },
 "Music Video": {
    "label": "Music Video",
    "children": {
      "Bad Habits": {
        "label": "Bad Habits",
        "children": {
          "Ahmed Bakare": {
            "label": "Ahmed Bakare"
          }
        }
      },
      "Blurred Lines": {
        "label": "Blurred Lines",
        "children": {
          "Emily Ratajkowski": {
            "label": "Emily Ratajkowski"
          },
          "Elle Evans": {
            "label": "Elle Evans"
          }
        }
      }
    }
  }
};  

Мой текущий подход:

menu = []
groupDict = df.groupby('type').apply(lambda g: g.drop('type', axis=1).to_dict(orient='records')).to_dict()
for key, value in groupDict.items():
    menu.append(dict(type=key,children=str(value)))

Однако результат не приходит, как я ожидал.

[{'type': 'Movie',
  'children': "[{'cast': 'Daniel Craig', 'title': 'Sky Fall'}, {'cast': 'Leonardo Dicaprio', 'title': 'Titanic'}, {'cast': 'Judi Dench', 'title': 'Sky Fall'}, {'cast': 'Kate Winslet', 'title': 'Titanic'}]"},
 {'type': 'Music Video',
  'children': "[{'cast': 'Ahmed Bakare', 'title': 'Bad Habits'}, {'cast': 'Emily Ratajkowski', 'title': 'Blurred Lines'}, {'cast': 'Elle Evans', 'title': 'Blurred Lines'}]"}]
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
27
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я сделал небольшую модификацию из этого поста: https://stackoverflow.com/a/43765794/19042045

Он принимает входные данные csv, поэтому вы можете легко преобразовать его из фрейма данных в csv.

  1. test.csv
type,title ,cast
Movie,Sky Fall ,Daniel Craig
Music Video,Bad Habits ,Ahmed Bakare
Movie,Titanic ,Leonardo Dicaprio
Movie,Sky Fall ,Judi Dench
Movie,Titanic ,Kate Winslet
Music Video,Blurred Lines ,Emily Ratajkowski
Music Video,Blurred Lines ,Elle Evans
  1. test.py
import csv
from collections import defaultdict


def ctree():
    """ One of the python gems. Making possible to have dynamic tree structure.

    """
    return defaultdict(ctree)


def build_leaf(name, leaf):
    """ Recursive function to build desired custom tree structure

    """
    res = {"label": name}

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

    return res


def main():
    """ The main thread composed from two parts.

    First it's parsing the csv file and builds a tree hierarchy from it.
    Second it's recursively iterating over the tree and building custom
    json-like structure (via dict).

    And the last part is just printing the result.

    """
    tree = ctree()
    # NOTE: you need to have test.csv file as neighbor to this file
    with open('test.csv') as csvfile:
        reader = csv.reader(csvfile)
        for rid, row in enumerate(reader):

            # skipping first header row. remove this logic if your csv is
            # headerless
            if rid == 0:
                continue

            # usage of python magic to construct dynamic tree structure and
            # basically grouping csv values under their parents
            leaf = tree[row[0]]
            for cid in range(1, len(row)):
                leaf = leaf[row[cid]]

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

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


# so let's roll
main()

  1. выполнить тест
python test.py
  1. результат
{
    "Movie": {
        "children": {
            "Sky Fall ": {
                "children": {
                    "Daniel Craig ": {
                        "label": "Daniel Craig "
                    }, 
                    "Judi Dench ": {
                        "label": "Judi Dench "
                    }
                }, 
                "label": "Sky Fall "
            }, 
            "Titanic ": {
                "children": {
                    "Kate Winslet ": {
                        "label": "Kate Winslet "
                    }, 
                    "Leonardo Dicaprio ": {
                        "label": "Leonardo Dicaprio "
                    }
                }, 
                "label": "Titanic "
            }
        }, 
        "label": "Movie"
    }, 
    "Music Video": {
        "children": {
            "Bad Habits ": {
                "children": {
                    "Ahmed Bakare ": {
                        "label": "Ahmed Bakare "
                    }
                }, 
                "label": "Bad Habits "
            }, 
            "Blurred Lines ": {
                "children": {
                    "Elle Evans": {
                        "label": "Elle Evans"
                    }, 
                    "Emily Ratajkowski ": {
                        "label": "Emily Ratajkowski "
                    }
                }, 
                "label": "Blurred Lines "
            }
        }, 
        "label": "Music Video"
    }
}

Привет, Нео, большое спасибо за помощь. Есть ли способ сделать это без записи файла csv?

LH1522 06.05.2022 12:09

Другие вопросы по теме