#json #python-3.x #pandas #dataframe
Вопрос:
У меня есть следующая json
строка, которую я хотел бы поместить в фрейм данных:
jsonstr = {
"id": "12345",
"ename": "A4.txt",
"Zoom1": {
"Zoom1_res": [
{
"code": "A1",
"x": 3211,
"y": 677,
"part": "11",
"lace": "29",
"name": "COVER"
},
{
"code": "A4",
"x": 3492,
"y": 1109,
"part": "10",
"lace": "19",
"name": "ARMOUR"
}
]
},
"iSize": {
"width": 4608,
"height": 3456
},
"Action": {
"AA": {
"detect": [
{
"class": "aa",
"prob": 0.92,
"Box": {
"x0": 4406,
"y0": 670,
"x1": 4558,
"y1": 760
}
},
{
"class": "aa",
"prob": 0.92,
"Box": {
"x0": 3762,
"y0": 655,
"x1": 3913,
"y1": 747
}
}
]
}
}
}
Используя json_read
следующим образом:
df =pd.read_json(jsonstr)
ВОЗВРАТ
id ename Zoom1
Zoom1_res 12345 A4.txt [{'code': 'A1', 'x': 3211, 'y': 677, 'part': '...
width 12345 A4.txt NaN
height 12345 A4.txt NaN
AA 12345 A4.txt NaN
iSize Action
Zoom1_res NaN NaN
width 4608.0 NaN
height 3456.0 NaN
AA NaN {'detect': [{'class': 'aa', 'prob': 0.92, 'Box...
и
pd.json_normalize(df['Action'])
возвращает ошибку
AttributeError: 'float' object has no attribute 'values'
Итак, я подумал, что применение
from ast import literal_eval
pd.json_normalize(df['Action'].apply(lambda x: literal_eval(x)["detect"]).explode())
возможно, это решит проблему, но они есть nan
в этой колонке, так что даже это не работает.
Чего я на самом деле хочу, так это:
В лучшем из всех миров: id, ename, code, x, y, x0, y0, x1, y1
Все остальные данные не имеют для меня никакой ценности.
Благодарен за любую информацию!
Ответ №1:
Смотрите, что ваш JSON вложен на нескольких уровнях,
1. Создание субкадров данных
df1 = pd.json_normalize(jsonstr, record_path=['Action','AA','detect'], meta=['id','ename'])
df2 = pd.json_normalize(jsonstr, record_path=['Zoom1','Zoom1_res'], meta=['id','ename'])
2. Перенос данных в NaN
Насколько я понимаю, gBOX и BOX-это одни и те же атрибуты, поэтому вы можете объединить их таким образом, ну, вы можете поиграть с ними и получить необходимые данные
df3 = df1.apply(lambda x: pd.Series(x.dropna().values), axis=1)
df3.columns = ['class','prob','x0','y0','x1','y1','id','ename']
3. Получите необходимые столбцы в соответствии с вашими данными
df4 = pd.merge(df3, df2, on=['id','ename'])
df4 = df4.iloc[:,[6,7,8,9,10,2,3,4,5]]
Комментарии:
1. Это действительно очень мило! Однако один комментарий:
, left_index=True, right_index=True
для меня это не работает. Спасибо!