Pyspark - получить имена атрибутов из файла json - PullRequest
0 голосов
/ 07 января 2019

Я новичок в pyspark. Мое требование - получить / извлечь имена атрибутов из вложенного файла JSON. Я попытался использовать json_normalize, импортированный из пакета панд. Он работает для прямых атрибутов, но никогда не выбирает атрибуты в атрибутах массива json. Мой JSON не имеет статической структуры. Это зависит от каждого документа, который мы получаем. Может ли кто-нибудь помочь мне с объяснением небольшого примера, приведенного ниже,

        {  
               "id":"1",
               "name":"a",
               "salaries":[  
                  {  
                     "salary":"1000"
                  },
                  {  
                     "salary":"5000"
                  }
               ],
               "states":{  
                  "state":"Karnataka",
                  "cities":[  
                     {  
                        "city":"Bangalore"
                     },
                     {  
                        "city":"Mysore"
                     }
                  ],
                  "state":"Tamil Nadu",
                  "cities":[  
                     {  
                        "city":"Chennai"
                     },
                     {  
                        "city":"Coimbatore"
                     }
                  ]
               }
            }  

Специально для элементов массива json.

Ожидаемый результат: Я бы название salaries.salary states.state states.cities.city``

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Вот еще одно решение для извлечения всех вложенных атрибутов из json

import json

result_set = set([])


def parse_json_array(json_obj, parent_path):
    array_obj = list(json_obj)
    for i in range(0, len(array_obj)):
        json_ob = array_obj[i]
        if type(json_obj) == type(json_obj):
            parse_json(json_ob, parent_path)
    return None


def parse_json(json_obj, parent_path):
    for key in json_obj.keys():
        key_value = json_obj.get(key)
        # if isinstance(a, dict):
        if type(key_value) == type(json_obj):
            parse_json(key_value, str(key) if parent_path == "" else parent_path + "." + str(key))
        elif type(key_value) == type(list(json_obj)):
            parse_json_array(key_value, str(key) if parent_path == "" else parent_path + "." + str(key))
        result_set.add((parent_path + "." + key).encode('ascii', 'ignore'))
    return None



file_name = "C:/input/sample.json"
file_data = open(file_name, "r")
json_data = json.load(file_data)
print json_data

parse_json(json_data, "")
print list(result_set)

Выход:

{u'states': {u'state': u'Tamil Nadu', u'cities': [{u'city': u'Chennai'}, {u'city': u'Coimbatore'}]}, u'id': u'1', u'salaries': [{u'salary': u'1000'}, {u'salary': u'5000'}], u'name': u'a'}
['states.cities.city', 'states.cities', '.id', 'states.state', 'salaries.salary', '.salaries', '.states', '.name']

Примечание:

My Python version: 2.7 
0 голосов
/ 13 марта 2019

Вы можете сделать это также.

data = { "id":"1", "name":"a", "salaries":[ { "salary":"1000" }, { "salary":"5000" } ], "states":{ "state":"Karnataka", "cities":[ { "city":"Bangalore" }, { "city":"Mysore" } ], "state":"Tamil Nadu", "cities":[ { "city":"Chennai" }, { "city":"Coimbatore" } ] } }



def dict_ittr(lin,data):

    for k, v in data.items():
        if type(v)is list:
            for l in v:
               dict_ittr(lin+"."+k,l)
        elif type(v)is dict:
            dict_ittr(lin+"."+k,v)
            pass
        else:
            print lin+"."+k

dict_ittr("",data)

выход

.states.state
.states.cities.city
.states.cities.city
.id
.salaries.salary
.salaries.salary
.name
0 голосов
/ 08 января 2019

Если вы рассматриваете json как словарь python, это должно сработать.

Я только что написал простую рекурсивную программу.

Сценарий

import json

def js_r(filename):
    with open(filename) as f_in:
        return(json.load(f_in))

g = js_r("city.json")
answer_d = {}
def base_line(g, answer_d):
    for key in g.keys():
        answer_d[key] = {}
    return answer_d

answer_d = base_line(g, answer_d)
def recurser_func(g, answer_d):
    for k in g.keys():
        if type(g[k]) == type([]): #If the value is a list
            answer_d[k] = {list(g[k][0].keys())[0]:{}}

        if type(g[k]) == type({}): #If the value is a dictionary
            answer_d[k] = {list(g[k].keys())[0]: {}} #set key equal to 
            answer_d[k] = recurser_func(g[k], answer_d[k])
    return answer_d
recurser_func(g,answer_d)


def printer_func(answer_d, list_to_print, parent):
    for k in answer_d.keys():
        if len(answer_d[k].keys()) == 1:
            list_to_print.append(parent)
            list_to_print[-1] += k
            list_to_print[-1] += "." + str(list(answer_d[k].keys())[0])
        if len(answer_d[k].keys()) == 0:
            list_to_print.append(parent)
            list_to_print[-1] += k
        if len(answer_d[k].keys()) > 1:
            printer_func(answer_d[k], list_to_print, k + ".")
    return list_to_print



l = printer_func(answer_d, [], "")
final = " ".join(l)
print(final)

Объяснение

base_line составляет словарь всех ваших базовых ключей.

recursur_func проверяет, является ли значение ключа списком или диктом, а затем добавляет в словарь ответов по мере необходимости, пока answer_d не будет выглядеть следующим образом: {'id': {}, 'name': {}, 'salaries': {'salary': {}}, 'states': {'state': {}, 'cities': {'city': {}}}}

После вызова этих двух функций в некотором смысле у вас есть словарь ключей. Затем printer_func - это рекурсивная функция для печати по вашему желанию.

Примечание:

Ваш вопрос похож на этот: Получите все ключи вложенного словаря , но поскольку у вас есть вложенный список / словарь вместо просто вложенного словаря, их ответы не будут работать для вас, но если вам нравится больше информации, то по этому вопросу обсуждается больше вопросов

РЕДАКТИРОВАТЬ 1

моя версия на Python 3.7.1

Я добавил средство открытия файлов json вверху. Я предполагаю, что json называется city.json и находится в том же каталоге

РЕДАКТИРОВАТЬ 2: Более подробное объяснение

Основная трудность, с которой я столкнулся при работе с вашими данными, заключается в том, что вы можете иметь бесконечно вложенные списки и словари. Это усложняет. Поскольку это было бесконечно возможное вложение, я понял, что это проблема рекурсии.

Итак, я создаю словарь словарей, представляющих структуру ключа, которую вы ищете. Сначала я начну с базовой линии.

base_line делает {'id': {}, 'name': {}, 'salaries': {}, 'states': {}} Это словарь пустых словарей. Я знаю это, когда ты печатаешь. Каждая ключевая структура (например, states.state) начинается с одного из этих слов.

рекурсии

Затем я добавляю все дочерние ключи, используя recursur_func. Когда задан словарь g, эта функция для цикла по всем ключам в этом словаре и (при условии, что answer_d имеет каждый ключ, который есть у g) для каждого ключа добавит эти ключи-потомки к answer_d.

Если ребенок это словарь. Затем я повторяю с заданным словарем g, который теперь является частью словаря, который относится к дочерним элементам, а answer_d является частью_ответа answer_d, который относится к дочернему элементу.

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