У меня есть фрейм данных с полем fields
, которое представляет собой список диктов (все строки имеют одинаковый формат). Вот как структурирован фрейм данных:
formId fields
123 [{'number': 1, 'label': 'Last Name', 'value': 'Doe'}, {'number': 2, 'label': 'First Name', 'value': 'John'}]
Я пытаюсь распаковать столбец fields
, чтобы он выглядел так:
formId Last Name First Name
123 Doe John
Код, который у меня есть на данный момент:
for i,r in df.iterrows():
for field in r['fields']:
df.at[i, field['label']] = field['value']
Однако это не кажется самым эффективным способом. Есть ли лучший способ добиться этого?
🤔 А знаете ли вы, что...
С Python можно создавать кросс-платформенные приложения для Windows, macOS и Linux.
Вы можете использовать .apply и .concat для преобразования диктовок в серии. Наконец, .pivot для преобразования столбца в заголовки.
Данные:
import pandas as pd
data = {"formId": 123, "fields": [{'number': 1, 'label': 'Last Name', 'value': 'Doe'},
{'number': 2, 'label': 'First Name', 'value': 'John'}]}
df = pd.DataFrame(data=data)
Код:
df = (pd
.concat(objs=[df, df.pop("fields").apply(func=pd.Series)], axis=1)
.pivot(index = "formId", columns = "label", values = "value")
.reset_index()
.rename_axis(mapper=None, axis=1)
)
print(df)
Выход:
formId First Name Last Name
0 123 John Doe
Лично я бы построил новый фрейм данных:
df = pd.DataFrame(
[
{"formId": form_id, **{f["label"]: f["value"] for f in fields}}
for form_id, fields in zip(df["formId"], df["fields"])
]
)
print(df)
Распечатки:
formId Last Name First Name
0 123 Doe John
Решение:
v = pd.concat([pd.json_normalize(x) for x in df["fields"]]).pivot_table(
columns = "label", values = "value", aggfunc=list
)
out = df[["formId"]].join(v.explode(v.columns.tolist(), ignore_index=True))
Результат с использованием примера ввода из OP:
formId First Name Last Name
0 123 John Doe
Также работает для нескольких строк. Для этого примера введите:
df = pd.DataFrame(
{
"formId": [123, 456],
"fields": [
[
{"number": 1, "label": "Last Name", "value": "Doe"},
{"number": 2, "label": "First Name", "value": "John"},
],
[
{"number": 1, "label": "Last Name", "value": "Smith"},
{"number": 2, "label": "First Name", "value": "Jack"},
],
],
}
)
Результат:
formId First Name Last Name
0 123 John Doe
1 456 Jack Smith