Как извлечь значения из вложенного массива JSON с помощью панд - PullRequest
0 голосов
/ 12 февраля 2019

У меня большой файл JSON (400 тыс. Строк).Я пытаюсь выделить следующее:

Политики- "описание"

элементы политики - "пользователи" и "значения базы данных"

ФАЙЛ JSON - https://pastebin.com/hv8mLfgx

Ожидаемый вывод от Pandas: https://imgur.com/a/FVcNGsZ

Все после «Элементы политики» повторяется точно так же по всему файлу.Я попробовал код ниже, чтобы изолировать «пользователей».Кажется, это не работает, я пытаюсь выгрузить все это в CSV.

Редактировать * здесь было решение, которое я пытался попробовать, но не смог заставить его работать правильно - Глубоко вложенный ответ JSON на pandas dataframe

from pandas.io.json import json_normalize as Jnormal
import json
import pprint, csv
import re

with open("Ranger_Policies_20190204_195010.json") as file:
    jsonDF = json.load(file)
    for item in jsonDF['policies'][0]['policyItems'][0]:
        print ('{} - {} - {}'.format(jsonDF['users']))

РЕДАКТИРОВАТЬ 2: У меня есть некоторый рабочий код, который может захватить некоторые из пользователей, но он не всех их.Только 11 из 25.

from pandas.io.json import json_normalize as Jnormal
import json
import pprint, csv
import re

with open("Ranger_Policies_20190204_195010.json") as file:
    jsonDF = json.load(file)
    pNode = Jnormal(jsonDF['policies'][0]['policyItems'], record_path='users')
    print(pNode.head(500))

РЕДАКТИРОВАТЬ 3: Это окончательная рабочая копия, однако я все еще не копирую все мои данные таблицы.Я установил цикл, чтобы просто игнорировать все.Захватите все, и я бы отсортировал его в Excel. У кого-нибудь есть идеи, почему я не могу записать все значения TABLE?

    json_data = json.load(file)
    with open("test.csv", 'w', newline='') as fd:
        wr = csv.writer(fd)
        wr.writerow(('Database name', 'Users', 'Description', 'Table'))
        for policy in json_data['policies']:
            desc = policy['description']
            db_values = policy['resources']['database']['values']
            db_tables = policy['resources']['table']['values']
            for item in policy['policyItems']:
                users = item['users']
                for dbT in db_tables:
                    for user in users:
                        for db in db_values:
                            _ = wr.writerow((db, user, desc, dbT))```

Ответы [ 2 ]

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

Панды здесь излишни: достаточно стандартного модуля CSV.Вам нужно просто перебрать политики для извлечения описания значений базы данных, затем для policyItems для извлечения пользователей:

with open("Ranger_Policies_20190204_195010.json") as file:
    jsonDF = json.load(file)
with open("outputfile.csv", newline='') as fd:
    wr = csv.writer(fd)
    _ = wr.writerow(('Database name', 'Users', 'Description'))
    for policy in js['policies']:
        desc = policy['description']
        db_values = policy['resources']['database']['values']
        for item in policy['policyItems']:
            users = item['users']
            for user in users:
                for db in db_values:
                    if db != '*':
                        _ = wr.writerow((db, user, desc))
0 голосов
/ 12 февраля 2019

Вот один из способов сделать это, и давайте предположим, что ваши json данные находятся в переменной с именем json_data

from itertools import product

def make_dfs(data):
    cols = ['db_name', 'user', 'description']

    for item in data.get('policies'):
        description = item.get('description')
        users = item.get('policyItems', [{}])[0].get('users', [None])
        db_name = item.get('resources', {}).get('database', {}).get('values', [None])
        db_name = [name for name in db_name if name != '*']
        prods = product(db_name, users, [description])
        yield pd.DataFrame.from_records(prods, columns=cols)

df = pd.concat(make_dfs(json_data), ignore_index=True)

print(df)

   db_name          user                               description
0    m2_db          hive  Policy for all - database, table, column
1    m2_db  rangerlookup  Policy for all - database, table, column
2    m2_db     ambari-qa  Policy for all - database, table, column
3    m2_db          af34  Policy for all - database, table, column
4    m2_db          g748  Policy for all - database, table, column
5    m2_db          hdfs  Policy for all - database, table, column
6    m2_db          dh10  Policy for all - database, table, column
7    m2_db          gs22  Policy for all - database, table, column
8    m2_db          dh27  Policy for all - database, table, column
9    m2_db          ct52  Policy for all - database, table, column
10   m2_db  livy_pyspark  Policy for all - database, table, column

Проверено на Python 3.5.1 и pandas==0.23.4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...