如何将含JSON格式字符串列的Pandas DataFrame转换为标准展开结构
解析并展开Pandas DataFrame中的JSON字符串列
问题场景
现有一个Pandas DataFrame,其中response列存储的是带有非标准格式的JSON字符串(来自数据库),原始数据如下:
| id | date | gender | response |
|---|---|---|---|
| 1 | 1/14/2021 | M | "{'score':3,'reason':{'description':array(['a','b','c'])}" |
| 2 | 5/16/2020 | F | "{'score':4,'reason':{'description':array(['x','y','z'])}" |
需要将response列解析为字典后展开,得到如下结构的标准DataFrame:
| id | date | gender | score | description |
|---|---|---|---|---|
| 1 | 1/14/2021 | M | 3 | a |
| 1 | 1/14/2021 | M | 3 | b |
| 1 | 1/14/2021 | M | 3 | c |
| 2 | 5/16/2020 | F | 4 | x |
| 2 | 5/16/2020 | F | 4 | y |
| 2 | 5/16/2020 | F | 4 | z |
解决方案
可以通过字符串清理+JSON解析+数组展开三步实现,具体代码如下:
1. 构造示例数据(已有DataFrame可跳过)
import pandas as pd import json # 模拟原始DataFrame df = pd.DataFrame({ 'id': [1, 2], 'date': ['1/14/2021', '5/16/2020'], 'gender': ['M', 'F'], 'response': [ "\"{'score':3,'reason':{'description':array(['a','b','c'])}\"", "\"{'score':4,'reason':{'description':array(['x','y','z'])}\"" ] })
2. 清理非标准JSON字符串
原始response列存在不符合JSON规范的格式:外层带双引号、内部用单引号、数组用array()格式,需先处理:
# 清理格式:去掉外层引号、替换单引号为双引号、将array(...)转为标准数组格式 df['response_clean'] = df['response'].str.strip('"') \ .str.replace("'", '"') \ .str.replace(r'array\((\[.*?\])\)', r'\1', regex=True)
3. 解析JSON并合并数据
用pd.json_normalize解析嵌套JSON,再和原始数据的关键列合并:
# 解析清理后的JSON字符串为扁平DataFrame response_df = pd.json_normalize(df['response_clean'].apply(json.loads)) # 合并原始列(id/date/gender)和解析后的列 merged_df = pd.concat([df[['id', 'date', 'gender']], response_df], axis=1)
4. 展开数组列
用explode方法将description数组的每个元素拆分为单独行:
# 展开数组列并重命名 final_df = merged_df.explode('reason.description').rename(columns={'reason.description': 'description'}) # 重置索引(可选) final_df = final_df.reset_index(drop=True)
最终结果
执行后final_df即为目标结构,打印输出:
id date gender score description 0 1 1/14/2021 M 3 a 1 1 1/14/2021 M 3 b 2 1 1/14/2021 M 3 c 3 2 5/16/2020 F 4 x 4 2 5/16/2020 F 4 y 5 2 5/16/2020 F 4 z
内容的提问来源于stack exchange,提问作者Sudhakar Samak
相关产品推荐
相关产品推荐

