У меня есть следующий фрейм данных Pandas (с именем dx):
_id user_type
0 {'$oid': '5b9058462f38434ab0d85cd3'} 1
1 {'$oid': '5b9058462f38434ab0d85ce9'} 1
2 {'$oid': '5b9058462f38434ab0d85ced'} 1
3 {'$oid': '5b9058462f38434ab0d85cee'} 1
4 {'$oid': '5b9058462f38434ab0d85cef'} 1
Он получен из большого JSON (более или менее 500 000 строк и больше столбцов, чем в этом примере), как вы можете видеть, _id содержит вложенный JSON.
В этом примере моя цель - получить новый столбец с именем oid с oid-код:
_id user_type oid
0 {'$oid': '5b9058462f38434ab0d85cd3'} 1 5b9058462f38434ab0d85cd3
1 {'$oid': '5b9058462f38434ab0d85ce9'} 1 5b9058462f38434ab0d85ce9
2 {'$oid': '5b9058462f38434ab0d85ced'} 1 5b9058462f38434ab0d85ced
3 {'$oid': '5b9058462f38434ab0d85cee'} 1 5b9058462f38434ab0d85cee
4 {'$oid': '5b9058462f38434ab0d85cef'} 1 5b9058462f38434ab0d85cef
Я добился результатов, используя следующий фрагмент:
dx['oid']=None
for i in dx.index:
dx['oid'][i]=dx.at[i,'_id']['$oid']
Это дает мне то, что я ищу, но очень-очень медленно. На заполнение столбца примера, в котором всего 5 строк, уходит 3-4 минуты!
Как я могу оптимизировать создание нового столбца на основе других столбцов со значениями JSON?
Я не могу использовать регулярное выражение, потому что вложенный JSON является основным сложным, чем тот, который в примере.






Это столбец типа object, который содержит один dict в ячейке, поэтому
df['$oid']=df['_id'].map(lambda x : x['$oid'])
Или
s=df['_id'].apply(pd.Series)
s
#df=pd.concat([df,s],axis=1)
Out[601]:
$oid
0 5b9058462f38434ab0d85cd3
1 5b9058462f38434ab0d85ce9
2 5b9058462f38434ab0d85ced
3 5b9058462f38434ab0d85cee
4 5b9058462f38434ab0d85cef
Вы можете использовать operator.itemgetter. Невозможно векторизованное решение, поскольку ваша входная серия имеет object dtype.
from operator import itemgetter
field_name = '$oid'
df[field_name] = list(map(itemgetter(field_name), df['_id']))
Доступны более общие решения, см. Разделение словаря / списка внутри столбца Pandas на отдельные столбцы.