Pandas: JSON нормализовать столбец со списком диктов в столбцыPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Pandas: JSON нормализовать столбец со списком диктов в столбцы

Сообщение Anonymous »

У меня есть файл данных, состоящий из целого набора файлов JSON, который используется в качестве реляционной базы данных. Поместить их в pandas несложно, но я пытаюсь создавать табличные отчеты, объединяющие данные из нескольких столбцов и нескольких фреймов данных. Каждая строка таблицы имеет поле идентификатора, на которое ссылаются одна или несколько ячеек в других таблицах, поэтому я могу выполнять соединения так же, как в SQL.
Однако некоторые из этих ключей/идентификаторов содержится во вложенных объектах JSON, которые находятся в отдельных ячейках. Например, один столбец содержит список диктовок, и каждый из этих диктовок содержит пару пар ключ:значение, представляющих метаданные тега ключ:значение для объекта в заданной строке кадра данных. Первая пара ключ:значение — это идентификатор, который ссылается на ключ тега в другой таблице, вторая пара ключ:значение содержит фактическое значение тега. Таким образом, конечная цель — извлечь эти теги ключ/значение и поместить значения в столбец, названный в честь ключа. И мне нужно сделать это для стольких тегов, сколько существует, число, которое меняется от одной строки к другой.
Если я нормализую json, этот список расширится. на столбцы в кадре данных, которые имеют числовые индексы (соответствующие списку).
Входящий JSON выглядит следующим образом:

Код: Выделить всё

deviceJSON = {
"devices": [
{
"name": "foo",
"noteIds": [],
"vendor": "Aruba",
"model": "2920F",
"tags": [],
"id": ,
},
{
"location": {
"floor": ,
"coord": {
"x": 100,
"y": 200
}
},
"name": "bar",
"noteIds": ["32b60e81-8f9d-4ea2-9af0-8e441d31649b"],
"vendor": "Cisco",
"model": "6500",
"tags": [
{
"tagKeyId": "68a9a2e4-9d03-42dd-8744-ed0d241f1746",
"value": "IDF 1"
},
{
"tagKeyId": "22a1adc4-bf73-4c52-a3f2-3bfca9d64011",
"value": "e-Waste"
}
],
"id": ,
}
]
}

deviceDF=pd.DataFrame(deviceJSON['devices'])
Поэтому при импорте этого JSON в Pandas тегиnoteIds, но это выходит за рамки этого вопроса< /em>) импортируется в один столбец, и содержимое этого столбца представляет собой список, содержащийся в этом словаре.
В конечном итоге мне нужно добраться до столбца с ключом тега либо как tag_keyname, либо просто keyname, а также значения в этом столбце (ключевое имя находится в другом Dataframe, индексированном tagKeyId):

Код: Выделить всё

tagKeysJSON = {
"tagKeys": [
{
"key": "IDF",
"id": "68a9a2e4-9d03-42dd-8744-ed0d241f1746",
},
{
"key": "Disposition",
"id": "22a1adc4-bf73-4c52-a3f2-3bfca9d64011",
}
]
}

tagKeysDF=pd.DataFrame(tagKeysJSON['tagKeys'])
Когда я это делаю:

Код: Выделить всё

deviceDF=deviceDF.join(pd.json_normalize(deviceDF.tags))

Я получаю столбцы, помеченные для индекса списка в тегах, содержащих словарь:
Столбец 0:

Код: Выделить всё

{"tagKeyId": "68a9a2e4-9d03-42dd-8744-ed0d241f1746","value": "IDF 1"}
столбец 1:

Код: Выделить всё

{"tagKeyId": "22a1adc4-bf73-4c52-a3f2-3bfca9d64011","value": "e-Waste"}
Поскольку количество тегов в списке может варьироваться и они могут располагаться в любом порядке, я не могу выполнить еще один этап нормализации и сохранить правильные значения с соответствующими ключами. , потому что еще один раунд нормализации оставляет мне столбцы tagKeyId и value вместо помещения значения в столбец для соответствующего ключа.
Я уже делал это раньше, но это устарело и к тому же неэффективно:

Код: Выделить всё

tagsRawDF=deviceDF[['id','tags']]
tagsListDF=pd.DataFrame()
tagnameList=[]

for row in tagsRawDF.iterrows():
taglist=row[1][1]
df_dict={'deviceId' : row[1][0]}
for tag in row[1][1]:
tagrec=tagKeysDF.loc[tagKeysDF["id"]==tag['tagKeyId']]
tagname='tag_'+tagrec.key.values[0].replace(" ","_")

# Have we seen this tag name before?
# (this list is being built to be used later in the output phase)
if tagname not in tagnameList : tagnameList.append(tagname)

df_dict[tagname]=tag['value']
tmp_df = pd.DataFrame(df_dict, index=[0])

tagsListDF = tagsListDF._append(tmp_df) # append the tmp_df to our final df

tagsListDF.reset_index(drop=True)

deviceDF=pd.merge(deviceDF, tagsListDF, left_on='id', right_on='id',how='left')

Обычное сообщение об ошибке:
FutureWarning: Series.getitem рассматривает ключи как позиции устарел. В будущей версии целочисленные ключи всегда будут рассматриваться как метки (в соответствии с поведением DataFrame). Чтобы получить доступ к значению по позиции, используйте ser.iloc[pos]
для тега в строке[1][1]:
Это странно специфично, но в то же время бесполезно, поскольку мне не удалось найти никакой хорошей документации, объясняющей, как провести рефакторинг кода для использования вместо него iloc.
Итак, Я немного застрял в том, как на самом деле подойти к этому - это было бы просто, если бы количество тегов было предсказуемым, но теперь это превышает мои ограниченные знания о Pandas (и хотя документация хороша, мне не поможет, если Я даже не знаю, что я на самом деле ищу).

Подробнее здесь: https://stackoverflow.com/questions/791 ... to-columns
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»