Вложенные словари фреймов данных Python конвертируются в JSON

Я изо всех сил пытаюсь написать переносимый код для проблемы, с которой я сталкиваюсь. У меня есть большой набор данных, структурированных как вложенные словари, и на «нижнем» уровне указанных гнезд (не обязательно одинаковое количество уровней) У меня есть Pandas DataFrames. Я просто хочу пройти через вложенный словарь ввода и преобразовать все Pandas DataFrames в json и вернуть ту же структуру, которая была введена. Ниже приведен пример кода того, что я пробовал до сих пор.

import pandas as pd

a = [1,2,3,4]
b = [-1,-2,-3,-4]
c = [0,1,-1,0]
d = [1,1,1,-1]

names = ['one','two','three','four']
columns=[f"col_{name}" for name in names]
index=[f"ind_{name}" for name in names]

df_1 = pd.DataFrame([a,b,c,d], columns=columns, index=index)
df_2 = pd.DataFrame([b,c,d,a], columns=columns, index=index)
df_3 = pd.DataFrame([c,d,a,b], columns=columns, index=index)
df_4 = pd.DataFrame([d,a,b,c], columns=columns, index=index)
df_5 = pd.DataFrame([a,a,d,c], columns=columns, index=index)

x = {
    'a': {
        'a1': df_1,
        'a2': df_2,
    },
    'b': {
        'b1': df_3,
    },
    'c': {
        'c1': {
            'c11': df_4,
        }
    },
    'd': df_5
}

def nested_dicts(d):
    for k, v in d.items():
        if isinstance(v, pd.DataFrame):
            return {k: v.T.to_json()}
        else:
            return nested_dicts(v)

d = nested_dicts(x)
for k in d.keys():
    print(k)
    print()

Я пробовал это столько раз, сколько я могу думать, но это самое простое описание моей проблемы. Мне нужно иметь возможность передать это веб-службе внешнего интерфейса, поэтому мне нужно преобразовать DataFrames в json, но я хочу сохранить иерархическую структуру только с преобразованием df_1,..., df_5 в их значения json.

Если «лучший» способ — это использовать генератор, или если есть что-то, чего я не вижу (мой мозг сейчас немного поджарился), я весь в ушах. Любая помощь будет оценена по достоинству.

Проверьте свою рекурсию

MaNKuR 25.01.2019 05:07

??? Не помогает с моим жареным мозгом. Если v — это DataFrame, я конвертирую его в json и возвращаю результат. В противном случае я передаю указанный v вниз, чтобы проверить еще раз. Если вы можете указать мне соответствующую ссылку, я был бы очень признателен.

Jeff 25.01.2019 05:14

Собираюсь ложиться спать, поэтому я не собираюсь входить в свой компьютер, чтобы проверить прямо сейчас, но я думаю, что возвращение {k: nested_dicts(v)} поможет. утром проверю

Jeff 25.01.2019 06:20

Почему в нижней части вложенной структуры Pandas DataFrames? Что все это должно концептуально представлять? Я думаю, что должны быть более простые структуры для того же намерения.

smci 25.01.2019 08:52

@smci вполне может быть, но это проблема, связанная с работой, и это структура, которую мне дают, к сожалению.

Jeff 25.01.2019 12:33

Не совсем уверен, для чего минусование. Я довольно долго пытался найти что-то, что работает, а также пробовал все, что мог придумать, и в конце концов решил обратиться за помощью сюда. Разве не для этого существует SO?

Jeff 25.01.2019 17:34
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
6
880
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

def iterdict(d):
    pandas = pd
    for k,v in d.items():
        if isinstance(v, dict):
            iterdict(v)
        else:
            if type(v) == pandas.core.frame.DataFrame:
                print("\nthis is pandas !\n\n" , v)


iterdict(x) 

>> 

this is pandas !

            col_one  col_two  col_three  col_four
ind_one          1        2          3         4
ind_two         -1       -2         -3        -4
ind_three        0        1         -1         0
ind_four         1        1          1        -1

this is pandas !

            col_one  col_two  col_three  col_four
ind_one         -1       -2         -3        -4
ind_two          0        1         -1         0
ind_three        1        1          1        -1
ind_four         1        2          3         4

this is pandas !

            col_one  col_two  col_three  col_four
ind_one          0        1         -1         0
ind_two          1        1          1        -1
ind_three        1        2          3         4
ind_four        -1       -2         -3        -4

this is pandas !

            col_one  col_two  col_three  col_four
ind_one          1        1          1        -1
ind_two          1        2          3         4
ind_three       -1       -2         -3        -4
ind_four         0        1         -1         0

this is pandas !

            col_one  col_two  col_three  col_four
ind_one          1        2          3         4
ind_two          1        2          3         4
ind_three        1        1          1        -1
ind_four         0        1         -1         0


Я добавил pandas = pd, потому что иначе тип 'pandas' не будет распознан

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

Две вещи, которые следует учитывать.

  1. Рекурсивный метод. Прочтите внимательно. То, как вы реализовали, неверно.
  2. Лучше копировать исходный диктофон до тех пор, пока вы не захотите изменить исходный.

Вот решение, которое, я думаю, должно работать.

import copy
import pandas as pd

def nested_dicts(d):
    for k, v in d.items():
        if isinstance(v, pd.DataFrame):
            d[k] = v.T.to_json()
        else:
            d[k] = nested_dicts(v)
    return d

d = nested_dicts(copy.deepcopy(x))   # Deepcopy to keep x intact

Ваше здоровье!

Большое спасибо, что нашли время, чтобы объяснить это @MaNKuR Самая большая проблема, с которой я столкнулся, заключается в том, что структура не сохранялась. Это была одна из тех относительно простых вещей, которые я должен был понять, но мне просто нужна была другая пара глаз, чтобы указать мне правильное направление.

Jeff 25.01.2019 17:38

Рад, что тебе помогло :)

MaNKuR 26.01.2019 04:56

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