Получать панды dataframe из вложенных словарей? - PullRequest
0 голосов
/ 13 февраля 2019

Я новичок в Python и не смог найти хорошего ответа на мою проблему после долгого поиска.Я пытаюсь создать фрейм данных Pandas из списка словарей.

Мой список вложенных словарей следующий:

{'category_1': [{'a': '151',
   'b': '116',
   'c': '86'}],
 'category_2': [{'d': '201',
   'e': '211',
   'f': '252'},
  {'d': '-1',
   'e': '-9',
   'f': '-7'}],
 'category_3': {'g': 'Valid',
   'h': None,
   'i': False,
   'j': False},
 'category_4': {'k': None,
   'l': None,
   'm': None,
   'n': None}}

И мой вывод должен быть

    a     b    c    d       e       f       g      h     i      j         k    l    m     n  
 0  151   116  86   201,-1  211,-9  252,-7  valid None  False False  None None  None None

То, что я пробовал, я могу сделать категорию 1,3,4, но не могу определить 2-ую категорию, которую я попробовал concat и для вложенного цикла, чтобы получить его

ex=pd.concat([pd.Series(d) for d in (eg1)], axis=1).T

Затем слить его.Как я уже сказал, не мог понять в целом!

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

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

flattened_dict = {}

def flatten(obj, name = ''):
    if isinstance(obj, dict):
        for key, value in obj.items():
            flatten(obj[key], key)
    elif isinstance(obj, list):
        for e in obj:
            flatten(e)
    else:
        if obj == 'null':
            obj = None
        flattened_dict[name] = [obj] 

flatten(eg1)

Результат: enter image description here

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

eg1 = { 
 "my_list": {
    "category_1": [
        {
            "a": "151",
            "b": "116",
            "c": "86"    
        }
    ],
    "category_2": [
        {
            "d": "201",
            "e": "211",
            "f": "252"
        },
        {
            "d": "-1 ",
            "e": "-9",
            "f": "-7"
        }
    ],
    "category_3": {
        "g": "Valid",
        "h": "null",
        "i": "Invalid",
        "j": "Invalid"
    },
    "category_4": {
        "k": "null",
        "l": "null",
        "m": "null",
        "n": "null"
    }
}
}
0 голосов
/ 13 февраля 2019

Я написал короткую рекурсивную функцию, которая возвращает серию или конкатенацию нескольких серий, если один из ключей в вашем дикте (например, category_2) содержит список из нескольких диктов.

def expand(x):
    if type(x) == dict:
        return pd.Series(x)
    elif type(x) == list:
        return pd.concat([expand(i) for i in x])

Если я начну со словаря, который вы вставили в приведенном выше примере:

d = {'category_1': [{'a': '151',
   'b': '116',
   'c': '86'}],
 'category_2': [{'d': '201',
   'e': '211',
   'f': '252'},
  {'d': '-1',
   'e': '-9',
   'f': '-7'}],
 'category_3': {'g': 'Valid',
   'h': None,
   'i': False,
   'j': False},
 'category_4': {'k': None,
   'l': None,
   'm': None,
   'n': None}}

Тогда это всего лишь вопрос объединения всех серий, созданных рекурсивным методом, который я написал:

output = pd.concat([expand(value) for key, value in d.items()])

И объединение любых дублирующих индексов так, чтобы их элементы появлялись в одном ряду и разделялись запятыми.Я также преобразую ряд в df с одной строкой и несколькими столбцами:

output = pd.DataFrame(output.groupby(output.index).apply(lambda x: ','.join(x.astype(str)))).T

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

output

    a    b    c   d        e        f       g      h     i        j        k     l     m     n
0   151  116  86  201,-1   211,-9   252,-7  Valid  None  Invalid  Invalid  None  None  None  None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...