如何用Pandas将嵌套JSON转为去重分组的HTML表格?
解决Pandas嵌套JSON转层级化HTML表格(按项目分组去重)
核心思路
pd.json_normalize会把嵌套的Accounts数据展开成多行,导致项目信息重复。我们需要先按项目唯一标识(比如Project.Name+Project.ID)分组,提取每个项目的唯一信息,再把对应Accounts明细作为子表格嵌套到项目行下方,最终生成层级化的HTML表格。
步骤实现
1. 确认你的DataFrame结构
先假设你展开后的DataFrame长这样(字段名可根据实际情况调整):
import pandas as pd # 模拟json_normalize后的结果 data = [ {"Project.Name": "项目A", "Project.ID": "P001", "Account.ID": "A001", "Account.Amount": 1000}, {"Project.Name": "项目A", "Project.ID": "P001", "Account.ID": "A002", "Account.Amount": 2000}, {"Project.Name": "项目B", "Project.ID": "P002", "Account.ID": "A003", "Account.Amount": 1500} ] df = pd.DataFrame(data)
2. 按项目分组整理数据
用groupby聚合每个项目的账户明细,同时保留唯一的项目信息:
# 按项目唯一标识分组,提取账户明细作为子DataFrame grouped = df.groupby(['Project.Name', 'Project.ID']).apply( lambda x: x[['Account.ID', 'Account.Amount']].reset_index(drop=True) ).reset_index(name='Accounts')
这里用Project.Name+Project.ID分组是为了避免同名项目被错误合并,如果你能确保项目名称唯一,只用Project.Name也可以。
3. 生成层级化HTML表格
手动拼接HTML,让项目信息跨列显示,下方嵌入对应的账户明细:
def build_project_section(row): # 项目标题行:跨账户表格的所有列 account_col_count = row['Accounts'].shape[1] project_header = f""" <tr> <td colspan="{account_col_count}" style="font-weight: 700; background: #f5f5f5; padding: 8px;"> 项目名称:{row['Project.Name']} | 项目ID:{row['Project.ID']} </td> </tr> """ # 生成账户明细的HTML,去掉外层table标签 account_table = row['Accounts'].to_html(index=False, border=1) account_table = account_table.replace('<table border="1" class="dataframe">', '').replace('</table>', '') # 拼接当前项目的完整HTML块 return project_header + account_table # 生成所有项目的HTML内容 project_sections = ''.join(grouped.apply(build_project_section, axis=1)) # 包裹成完整的HTML表格 final_html = f""" <table border="1" cellpadding="6" cellspacing="0" class="dataframe"> {project_sections} </table> """ # 输出或保存HTML print(final_html)
自定义优化建议
- 扩展项目字段:如果项目还有其他信息(比如
Project.Description),直接在groupby参数里加入该字段,然后在build_project_section的标题行里添加显示即可。 - 样式美化:修改
style属性自定义背景色、字体、间距,或者添加CSS类来统一控制表格样式。 - 处理空账户:如果某个项目没有Accounts明细,可以在函数里加判断,显示“无账户明细”的提示行。
内容的提问来源于stack exchange,提问作者Dave M
相关产品推荐
相关产品推荐

