基于Dataframe构建层级节点结构字典并计算节点金额总和
层级嵌套节点结构字典的正确实现方案
需求说明
基于包含Nod、Levels、Parents、Amounts字段的DataFrame,构建层级嵌套的节点结构字典:
- 层级嵌套:1级节点包含2级子节点,2级节点包含3级子节点,以此类推
- 金额计算:每个节点的
Amounts值等于其所有直接子节点的Amounts总和
原代码存在的问题
原代码核心问题有两点:
- 重复节点处理错误:数据中存在重复
Nod(如8638出现两次),原代码直接覆盖记录,导致金额数据丢失 - 结构与计算逻辑不严谨:节点索引创建方式易生成空结构,求和函数未考虑叶子节点初始金额的正确传递逻辑
正确实现方案
步骤说明
- 预处理数据:合并重复
Nod的金额,避免数据丢失 - 构建节点映射:为每个节点创建独立结构,存储自身金额和子节点ID列表
- 层级倒序计算金额:从最高层级节点开始向上遍历,累加子节点金额到父节点
- 生成嵌套结构:从根节点(Level=1)出发,递归生成完整的嵌套字典
完整代码
import pandas as pd from io import StringIO data = """Nod Levels Parents Amounts 8616 1 NaN 0 8636 5 8648 0 8637 5 8635 0 8631 4 8630 0 8605 5 8609 8888882 8606 5 8609 339494 8609 4 8615 0 8613 6 8620 0 8614 6 8636 0 8615 3 8642 0 8618 6 8620 49832 8619 6 8636 11122 8620 5 8648 0 8621 4 8615 0 8622 5 8621 237837 8623 5 8621 0 8624 4 8615 0 8625 5 8624 87328732 8634 4 8627 0 8639 5 8634 0 8648 4 8627 0 8630 3 8642 0 8632 4 8615 0 8627 3 8642 0 8629 5 8609 -8378383 8633 5 8632 0 8635 4 8627 0 8638 5 8634 -93198318 8638 5 8634 32323 8642 2 8616 0""" # 读取数据并预处理:合并重复Nod的Amounts df = pd.read_csv(StringIO(data), sep=' ') df = df.groupby(['Nod', 'Levels', 'Parents'], as_index=False)['Amounts'].sum() # 1. 构建节点映射:每个节点存自身信息和子节点列表 node_map = {} for _, row in df.iterrows(): nod = row['Nod'] node_map[nod] = { 'Amounts': row['Amounts'], 'children': [] } # 2. 建立父子关联 root_nodes = [] for _, row in df.iterrows(): nod = row['Nod'] parent_nod = row['Parents'] if pd.isna(parent_nod): root_nodes.append(nod) else: # 将当前节点添加到父节点的children列表 node_map[parent_nod]['children'].append(nod) # 3. 从最高层级到最低层级计算父节点的Amounts # 获取所有层级并倒序排列 levels = sorted(df['Levels'].unique(), reverse=True) for level in levels: # 处理当前层级的所有节点 for _, row in df[df['Levels'] == level].iterrows(): nod = row['Nod'] parent_nod = row['Parents'] if not pd.isna(parent_nod): # 将当前节点的Amounts累加到父节点 node_map[parent_nod]['Amounts'] += node_map[nod]['Amounts'] # 4. 生成嵌套字典结构 def build_nested_structure(nod): node_data = {'Amounts': node_map[nod]['Amounts']} # 递归添加子节点 for child_nod in node_map[nod]['children']: node_data[child_nod] = build_nested_structure(child_nod) return node_data # 构建最终结果(根节点是Level=1的节点) result = {} for root_nod in root_nodes: result[root_nod] = build_nested_structure(root_nod) print(result)
代码说明
- 数据预处理:通过
groupby合并重复Nod的金额,确保数据完整性 - 节点映射:为每个节点保存初始金额和子节点ID列表,简化父子关联逻辑
- 层级倒序计算:从最底层节点开始向上累加,保证父节点金额计算基于最终的子节点金额
- 递归构建结构:从根节点出发,递归将子节点转换为嵌套字典,完全符合层级嵌套要求
内容的提问来源于stack exchange,提问作者Gogo78
相关产品推荐
相关产品推荐

