如何将含嵌套DataFrame的dataclass列表转换为多层索引DataFrame
实现方案
可以通过dataclasses.asdict + pd.json_normalize的组合实现,不需要手动拆分两类字段分别做表再拼接,逻辑更简洁统一。
前置依赖导入
import pandas as pd import dataclasses from dataclasses import dataclass
示例数据构造(用于复现测试)
@dataclass class User: name: str age: int hobbies: pd.DataFrame # 要求该字段对应DataFrame仅含1行 # 构造测试用的dataclass实例列表 user_list = [ User(name="张三", age=25, hobbies=pd.DataFrame([{"运动": "篮球", "阅读": "科幻小说", "游戏": "开放世界"}])), User(name="李四", age=28, hobbies=pd.DataFrame([{"运动": "跑步", "阅读": "历史传记", "游戏": "策略类"}])), User(name="王五", age=22, hobbies=pd.DataFrame([{"运动": "游泳", "阅读": "散文", "游戏": "角色扮演"}])), ]
核心实现代码
# 1. 把dataclass转成带嵌套字典的列表,同时把单行列的hobbies转为普通字典 record_list = [ {**dataclasses.asdict(u), "hobbies": u.hobbies.iloc[0].to_dict()} for u in user_list ] # 2. 用json_normalize展开嵌套字段,自定义分隔符避免和列名原有字符冲突 flat_df = pd.json_normalize(record_list, sep="|") # 3. 把扁平列直接转成要求的MultiIndex结构,非hobbies字段的下层索引用空占位符填充 flat_df.columns = pd.MultiIndex.from_tuples( [tuple(col.split("|")) if "|" in col else (col, "") for col in flat_df.columns] )
结果说明
输出的flat_df列结构完全符合需求:
- 上层索引包含
name/age/hobbies三类 name和age的下层索引为空占位符hobbies的下层索引对应原嵌套DataFrame的所有列名,数据完全展开无压缩
注意事项
如果你的hobbies列名本身包含|字符,可自行替换pd.json_normalize里的sep参数为其他不会出现的特殊字符即可。
内容的提问来源于stack exchange,提问作者A1122
相关产品推荐
相关产品推荐

