如何展开DataFrame列中的字典列表并重组数据
展开DataFrame嵌套列并高亮新增行
原始DataFrame结构
| id | name | code | date | Additional info |
|---|---|---|---|---|
| 01 | shirt | xyz123 | 2022-01-01 | [{'name': 'phone', 'code': 'ph123'}, {'name': 'car', 'code': 'cx2022'}, {}] |
| 02 | bike | bk001 | 2022-12-10 | [{}, {}, {}] |
| 03 | phone | ph987 | 2023-02-10 | [{'name': 'shirt', 'code': 'xyz456'}] |
需求说明
展开Additional info列,将每个非空字典的name、code值映射到对应列,移除Additional info列,同时为从嵌套字典生成的新增行添加加粗标注,最终得到如下结构的DataFrame:
预期结果
| id | name | code | date |
|---|---|---|---|
| 01 | shirt | xyz123 | 2022-01-01 |
| 01 | phone | ph123 | 2022-01-01 |
| 01 | car | cx2022 | 2022-01-01 |
| 02 | bike | bk001 | 2022-12-10 |
| 03 | phone | ph987 | 2023-02-10 |
| 03 | shirt | xyz456 | 2023-02-10 |
解决方案
以下是基于Pandas的实现代码:
import pandas as pd # 构造原始DataFrame data = [ {"id": "01", "name": "shirt", "code": "xyz123", "date": "2022-01-01", "Additional info": [{'name': 'phone', 'code': 'ph123'}, {'name': 'car', 'code': 'cx2022'}, {}]}, {"id": "02", "name": "bike", "code": "bk001", "date": "2022-12-10", "Additional info": [{}, {}, {}]}, {"id": "03", "name": "phone", "code": "ph987", "date": "2023-02-10", "Additional info": [{'name': 'shirt', 'code': 'xyz456'}]} ] df = pd.DataFrame(data) # 提取原始行(移除嵌套列) original_rows = df.drop(columns=["Additional info"]).copy() original_rows["is_expanded"] = False # 处理嵌套列生成新增行 expanded_rows = [] for _, row in df.iterrows(): # 过滤空字典,只保留有效数据 valid_info = [item for item in row["Additional info"] if item] for info in valid_info: new_row = row.drop("Additional info").copy() # 替换name和code为嵌套字典中的值 new_row["name"] = info["name"] new_row["code"] = info["code"] new_row["is_expanded"] = True expanded_rows.append(new_row) # 转换为DataFrame并合并原始行 expanded_df = pd.DataFrame(expanded_rows) final_df = pd.concat([original_rows, expanded_df]) # 排序:保持同一id下原始行在前,新增行在后 final_df = final_df.sort_values(by=["id", "is_expanded"], ascending=[True, False]) final_df = final_df.drop(columns=["is_expanded"]).reset_index(drop=True) # 为新增行添加加粗标记(用于Markdown渲染) expanded_indices = final_df.index.difference(original_rows.index) final_df.loc[expanded_indices, ["id", "name", "code", "date"]] = final_df.loc[expanded_indices].applymap(lambda x: f"**{x}**") # 输出Markdown格式结果 print(final_df.to_markdown(index=False))
代码说明
- 先分离原始行和处理嵌套列生成新增行,过滤空字典避免无效数据;
- 通过
is_expanded标记区分原始行与新增行,合并后排序保证原始行优先级; - 最后为新增行的字段添加
**标记,在Markdown渲染时自动显示为加粗效果。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

