Преобразование вложенного списка, содержащего многоуровневый словарь в Python - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть файл json с вложенными списками, содержащий многоуровневый словарь.Я пытаюсь создать питон DataFrame из этих данных.

Loading data:

data = []
with open('TREC_blog_2012.json') as f:
for line in f:
    data.append(json.loads(line))

Вывод данных:

IN LIST FORMAT: data[0] 

{'id': '1d3bc37004e71da2816dbfda8df90746',
'article_url': 'https://www.washingtonpost.com/express/wp/2012/01/03/month-of-muscle/',
'title': 'Month of Muscle',
'author': 'Vicky Hallett',
'published_date': 1325608933000,
'contents': [{'content': 'Express', 'mime': 'text/plain', 'type': 'kicker'},
{'content': 'Month of Muscle', 'mime': 'text/plain', 'type': 'title'},
{'content': 'By Vicky Hallett', 'mime': 'text/plain', 'type': 'byline'},
{'content': 1325608933000, 'mime': 'text/plain', 'type': 'date'},
{'content': 'SparkPeople trainer Nicole Nichols asks for only 28 days to get you into shape',
'mime': 'text/plain',
'type': 'deck'},
{'fullcaption': 'Nicole Nichols, front, chose backup exercisers with strong but realistic physiques to make the program less intimidating.',
'imageURL': 'http://www.expressnightout.com/wp-content/uploads/2012/01/SparkPeople28DayBootcamp.jpg',
'mime': 'image/jpeg',
'imageHeight': 201,
'imageWidth': 300,
'type': 'image',
'blurb': 'Nicole Nichols, front, chose backup exercisers with strong but realistic physiques to make the program less intimidating.'},
 {'content': 'If you’ve seen a Nicole Nichols workout before, chances are it was on YouTube. The fitness expert, known as just Coach Nicole to the millions of members of <a href="http://www.sparkpeople.com" target="_blank">SparkPeople.com</a>, has filmed dozens of routines for the free health website. The popular videos showcasing her girl-next-door style, gentle encouragement and clear cueing have built such a devoted following that the American Council on Exercise and Life Fitness just named her “America’s top personal trainer to watch.”',
'subtype': 'paragraph',
'type': 'sanitized_html',
'mime': 'text/html'},
{'content': '<strong>3. Prioritize.</strong> When people say they can’t fit exercise in their schedule, Nichols always asks, “How much TV do you watch?” Use your shows as a reward for your workout instead of the replacement, she suggests.',
'subtype': 'paragraph',
'type': 'sanitized_html',
'mime': 'text/html'},
{'role': '',
'type': 'author_info',
'name': 'Vicky Hallett',
'bio': 'Vicky Hallett is a freelancer and former MisFits columnist.'}],
'type': 'blog',
'source': 'The Washington Post'}

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

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

The method I tried:

df = pd.DataFrame(data)
test = pd.DataFrame(df['contents'][0])
test.head()

дает мне вывод df ['contents'] как

output received for test

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

TIA:)

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Я бы сделал что-то вроде этого:

new_data = []
for row in data: 
    if 'contents' in row:
        for content in row['contents']:
            new_dict = dict(row)
            del new_dict['contents']

            for key, value in content.items():
                new_dict['content_{}'.format(key)] = value

            new_data.append(new_dict)
    else:
        new_data.append(row)

Имейте в виду, что я создаю одну строку данных для каждого элемента в «содержимом».Таким образом, у вас будет 9 строк, соответствующих элементам в данных [0].

pd.DataFrame.from_dict(new_data)

enter image description here

В основном у вас есть два способа преобразовать вложенный диктат в 2D-фрейм данных: вы можете сохранить одну строку на элемент списка, новам нужно будет добавить много столбцов (по одному для каждого элемента вхождения в содержании, количество столбцов может сильно варьироваться и стать болью в шее) или путем добавления одной строки на элемент в содержимом.Я думаю, что последний подходит для вашего случая.

0 голосов
/ 20 сентября 2018

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

Эта часть может быть немедленно назначена столбцам кадра данных:

{'id': '1d3bc37004e71da2816dbfda8df90746',
'article_url': 'https://www.washingtonpost.com/express/wp/2012/01/03/month-of-muscle/',
'title': 'Month of Muscle',
'author': 'Vicky Hallett',
'published_date': 1325608933000}

Однако эту часть необходимо сначала назначить словарю в python, а затем можно извлечь столбцына pandas dataframe.

{'contents': [{'content': 'Express', 'mime': 'text/plain', 'type': 'kicker'}]}

Таким образом, ваш код может выглядеть следующим образом:

import pandas as pd

json_file = {'id': '1d3bc37004e71da2816dbfda8df90746',
'article_url': 'https://www.washingtonpost.com/express/wp/2012/01/03/month-of-muscle/',
'title': 'Month of Muscle',
'author': 'Vicky Hallett',
'published_date': 1325608933000,
'contents': [{'content': 'Express', 'mime': 'text/plain', 'type': 'kicker'}]
            }

df = pd.DataFrame.from_dict(json_file)
my_dict = df['contents'].values[0]
for key in my_dict.keys():
    df[key] = my_dict[key]

Вам придется распространить эту процедуру на другие подкаталоги вашего json-файла, если таковые существуют,При условии, что ни один ключ / узел в исходном файле json также не является ключом в под-словарях, этот код назначит все элементы под-словаря соответствующему столбцу в кадре данных.Если в вашем наборе данных есть несколько строк / файлов json, вы можете использовать эту процедуру для преобразования каждого json в кадр данных pandas, а затем вы можете добавить преобразованный json, теперь кадр данных, в основной глобальный кадр данных, строки которого каждыйсодержит информацию, извлеченную из одного файла JSON.

...