首页 > 解决方案 > Python:将列中的JSON结构扩展到同一数据框中的列

问题描述

我有一列由 JSON 结构化数据组成。我的df样子是这样的:

ClientToken                      Data
7a9ee887-8a09-ff9592e08245       [{"summaryId":"4814223456","duration":952,"startTime":1587442919}]
bac49563-2cf0-cb08e69daa48       [{"summaryId":"4814239586","duration":132,"startTime":1587443876}]

我想将其扩展为:

ClientToken                      summaryId         duration           startTime
7a9ee887-8a09-ff9592e08245       4814223456             952           1587442919
bac49563-2cf0-cb08e69daa48       4814239586             132           1587443876`

有任何想法吗?

标签: pythonjsonpandas

解决方案


你可以试试:

df[["ClientToken"]].join(df.Data.apply(lambda x: pd.Series(json.loads(x[1:-1]))))

说明

  1. 选择Data列并应用以下步骤:
    1. 因为 " Data" 内容被包装在一个列表中并且这是一个字符串,我们可以[]使用手动x[1:-1]删除(删除第一个和最后一个字符)。
    2. 由于"Data"列是 astring并且我们实际上想要 a JSON,因此我们需要对其进行转换。一种解决方案是使用模块中的json.loads()功能json。代码变成json.loads(x[1:-1])
    3. 然后,将 转换dictpd.Seriesusingpd.Series(json.loads(x[1:-1]))
  2. 使用 将这些新列添加到现有数据框中join。此外,您会注意到我使用 double[]来选择"ClientToken"列作为数据框。

代码+插图

import pandas as pd
import json

# step 1.1
print(df.Data.apply(lambda x: x[1:-1]))
# 0    {"summaryId":"4814223456","duration":952,"star...
# 1    {"summaryId":"4814239586","duration":132,"star...
# Name: Data, dtype: object

# step 1.2
print(df.Data.apply(lambda x: json.loads(x[1:-1])))
# 0    {'summaryId': '4814223456', 'duration': 952, '...
# 1    {'summaryId': '4814239586', 'duration': 132, '...
# Name: Data, dtype: object

# step 1.3
print(df.Data.apply(lambda x: pd.Series(json.loads(x[1:-1]))))
#     summaryId  duration   startTime
# 0  4814223456       952  1587442919
# 1  4814239586       132  1587443876

# step 2
print(df[["ClientToken"]].join(df.Data.apply(lambda x: pd.Series(json.loads(x[1:-1])))))
#                   ClientToken   summaryId  duration   startTime
# 0  7a9ee887-8a09-ff9592e08245  4814223456       952  1587442919
# 1  bac49563-2cf0-cb08e69daa48  4814239586       132  1587443876

编辑1:

似乎有些行listinData有多个dicts,您可以尝试:

df[["ClientToken"]].join(df.Data.apply(lambda x: [pd.Series(y)
                                                  for y in json.loads(x)]) \
                    .explode() \
                    .apply(pd.Series))

推荐阅读