Я хочу сгладить столбец JSON в Pandas DataFrame

У меня есть входной кадр данных df, который выглядит следующим образом:

id  e
1   {"k1":"v1","k2":"v2"}
2   {"k1":"v3","k2":"v4"}
3   {"k1":"v5","k2":"v6"}

Я хочу «сгладить» столбец «e», чтобы мой результирующий кадр данных был:

id  e.k1    e.k2
1   v1  v2
2   v3  v4
3   v5  v6

Как я могу это сделать? Я пытался использовать json_normalize, но без особого успеха.


person Symphony    schedule 13.04.2018    source источник


Ответы (2)


Вот как можно использовать pandas.io.json.json_normalize():

from pandas.io.json import json_normalize
df = df.join(json_normalize(df["e"].tolist()).add_prefix("e.")).drop(["e"], axis=1)
print(df)
#  e.k1 e.k2
#0   v1   v2
#1   v3   v4
#2   v5   v6

Однако, если ваш столбец на самом деле является str, а не dict, вам сначала нужно отобразить его с помощью json.loads():

import json
df = df.join(json_normalize(df['e'].map(json.loads).tolist()).add_prefix('e.'))\
    .drop(['e'], axis=1)
person pault    schedule 13.04.2018
comment
Вы можете захотеть df = df.reset_index() перед df.join, чтобы убедиться, что строки сопоставляются правильно. - person dominik; 12.09.2020
comment
@pault, как бы вы приняли это, если некоторые строки пусты для столбца с json. Ваше решение работает для меня со всеми строками, имеющими действительный json, но если у меня есть строки с пустым столбцом, я получаю сообщение об ошибке: AttributeError: объект 'float' не имеет атрибута 'items' - person Snapula; 18.01.2021

Если ваш столбец еще не является словарем, вы можете использовать map(json.loads) и применить pd.Series:

s = df['e'].map(json.loads).apply(pd.Series).add_prefix('e.')

Или, если это уже словарь, вы можете применить pd.Series напрямую:

s = df['e'].apply(pd.Series).add_prefix('e.')

Наконец, используйте pd.concat, чтобы соединить другие столбцы:

>>> pd.concat([df.drop(['e'], axis=1), s], axis=1).set_index('id')    
id e.k1 e.k2
1    v1   v2
2    v3   v4
3    v5   v6
person user3483203    schedule 13.04.2018