#python #json #numpy
#python #json #тупой
Вопрос:
У меня есть вложенные данные json, которые похожи на следующие:
[{'game':'001', 'animals': [{'name':'Dog', 'colour':'Red'}, {'name':'Horse', 'age':'6'},{'name':'Ostrich', 'location':'Africa'}]},{'game':'002', 'animals': [{'name':'Cat', 'colour':'Green'}, {'name':'Bison', 'location':'North America'},{'name':'Parrot', 'location':'Southeast Asia'}]}]
Моя цель — создать запись массива индикаторов для каждого животного (содержащегося в ‘name’), соответствующую элементам в переменной «animal_list»:
animal_list = ['Bison', 'Cat', 'Dog', 'Elephants', 'Horse', 'Ostrich', 'Parrot']
Таким образом, желаемая структура будет напоминать (выраженную в формате csv…но это иллюстративно только потому, что я ищу позиционный массив numpy):
Game, Bison, Cat, Dog, Elephants, Horse, Ostrich, Parrot
"001",0,0,1,0,1,1,0
"002",1,1,0,0,0,0,1
Я традиционно формировал это с помощью «двойного цикла» — сначала для «игровых» предметов; затем следует внутренний цикл, который просматривает «именные» предметы. Проблема в том, что у меня длинный список json, и на его выполнение уходит несколько часов.
Спасибо за вашу помощь!
Комментарии:
1. Пожалуйста, предоставьте код для вашего текущего подхода.
2. он все еще кажется недействительным
3. Почему бы не использовать pandas?
4. Если вы покажете нам свой традиционный метод, нам будет легче предложить улучшения. Это также облегчает тестирование.
5.
json
является строкой;loads
создает словарь. Существует только 2 способа доступа к элементам словаря — путем индексации ключей или черезitems
списки.numpy
у него нет магии, чтобы сделать что-то из этого быстрее.
Ответ №1:
Ниже приведена версия таблицы для pandas.
Вы всегда можете обратиться к ndarray
as df.values
import numpy as np
import pandas as pd
data = [{'game': '001', 'animals': [{'name':'Dog', 'colour':'Red'}, {'name':'Horse', 'age':'6'},{'name':'Ostrich', 'location':'Africa'}]},
{'game': '002', 'animals': [{'name':'Cat', 'colour':'Green'}, {'name':'Bison', 'location':'North America'},{'name':'Parrot', 'location':'Southeast Asia'}]}]
animal_list = ['Bison', 'Cat', 'Dog', 'Elephants', 'Horse', 'Ostrich', 'Parrot']
games = [d['game'] for d in data]
df = pd.DataFrame(np.zeros((len(games), len(animal_list))),
index=games, columns=animal_list)
for ix, g in enumerate(games):
a = [a['name'] for a in data[ix]['animals']]
df.loc[g, a] = 1
print(df)
Bison Cat Dog Elephants Horse Ostrich Parrot
001 0.0 0.0 1.0 0.0 1.0 1.0 0.0
002 1.0 1.0 0.0 0.0 0.0 0.0 1.0
Комментарии:
1. Большое спасибо за это. Намного элегантнее, чем цикл, который я использую. Вопрос — у меня сложилось впечатление, что поиск по фреймам данных происходит медленно. Может быть быстрее использовать массив numpy и добавлять?
2. в принципе, вы правы. но в вашем случае, поскольку исходные данные помечены строками, а не позициями, вам придется вручную преобразовать метки в индексы. Это, вероятно, будет стоить вам дороже и будет менее элегантно.