You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从DataTable中拆分不同层级高度的多组层级结构

嘿,我来帮你解决这个层级DataTable拆分的问题!先把你的示例数据整理得更清晰些,方便咱们梳理思路:

示例输入数据

AccountHierarchy Account
1
21
31
42
53
6

从数据能看出来,这是个典型的父子节点层级结构:1和6是根节点(没有父节点),2、3是1的子节点,4是2的子节点,5是3的子节点。拆分的核心需求应该是把这些独立的树结构(比如以1为根的树、以6为根的树)分开,或者给每个节点生成完整的层级路径对吧?

下面我给你两种常见场景的解决方案,分别用Python(pandas处理DataFrame)和C#(原生DataTable)来实现:


方案1:用Python Pandas生成层级路径+拆分独立树

如果你的DataTable是用pandas处理的,这段代码可以直接用:

import pandas as pd

# 加载示例数据(实际场景可以从文件/数据库读取)
data = {
    'Account': [1, 2, 3, 4, 5, 6],
    'Hierarchy Account': ['', 1, 1, 2, 3, '']
}
df = pd.DataFrame(data)

# 把空的父节点转为None,方便后续判断
df['Hierarchy Account'] = df['Hierarchy Account'].replace('', None)

# 构建「父节点→子节点列表」的映射,快速查找子节点
parent_child_map = df.groupby('Hierarchy Account')['Account'].apply(list).to_dict()

# 递归生成每个节点的完整层级路径(从根到当前节点)
def get_full_hierarchy_path(account):
    path = [account]
    parent = df.loc[df['Account'] == account, 'Hierarchy Account'].values[0]
    while parent is not None:
        path.insert(0, parent)
        parent = df.loc[df['Account'] == parent, 'Hierarchy Account'].values[0]
    return path

# 给原表添加层级路径列
df['Full Hierarchy Path'] = df['Account'].apply(get_full_hierarchy_path)

# 拆分出每个独立的树结构(每个根节点对应一个子树)
root_accounts = df[df['Hierarchy Account'].isna()]['Account'].tolist()
split_trees = {}

def collect_subnodes(node):
    """递归收集当前节点下的所有子节点"""
    nodes = [node]
    children = parent_child_map.get(node, [])
    for child in children:
        nodes.extend(collect_subnodes(child))
    return nodes

for root in root_accounts:
    split_trees[root] = collect_subnodes(root)

# 输出结果
print("带完整层级路径的表格:")
print(df)
print("\n拆分后的独立树结构:")
for root, nodes in split_trees.items():
    print(f"根节点{root}对应的所有节点:{nodes}")

运行后你会得到:

  • 每个节点的完整路径(比如4的路径是[1,2,4])
  • 拆分后的两个独立树:[1,2,4,3,5]和[6]

方案2:用C#处理原生DataTable

如果是在.NET环境下用DataTable,核心思路和Python一致,代码如下:

using System;
using System.Collections.Generic;
using System.Data;

class HierarchySplitter
{
    static void Main()
    {
        // 假设dt是你的输入DataTable
        DataTable dt = new DataTable();
        dt.Columns.Add("Account", typeof(int));
        dt.Columns.Add("Hierarchy Account", typeof(int)).AllowDBNull = true;
        dt.Rows.Add(1, DBNull.Value);
        dt.Rows.Add(2, 1);
        dt.Rows.Add(3, 1);
        dt.Rows.Add(4, 2);
        dt.Rows.Add(5, 3);
        dt.Rows.Add(6, DBNull.Value);

        // 1. 构建父子映射&识别根节点
        Dictionary<int, List<int>> parentChildMap = new Dictionary<int, List<int>>();
        List<int> rootAccounts = new List<int>();

        foreach (DataRow row in dt.Rows)
        {
            int account = (int)row["Account"];
            if (row["Hierarchy Account"] == DBNull.Value)
            {
                rootAccounts.Add(account);
            }
            else
            {
                int parent = (int)row["Hierarchy Account"];
                if (!parentChildMap.ContainsKey(parent))
                {
                    parentChildMap[parent] = new List<int>();
                }
                parentChildMap[parent].Add(account);
            }
        }

        // 2. 拆分每个根节点对应的子树,生成新的DataTable
        List<DataTable> splitTables = new List<DataTable>();
        foreach (int root in rootAccounts)
        {
            List<int> treeNodes = new List<int>();
            CollectSubnodes(root, treeNodes, parentChildMap);
            
            // 从原表筛选节点,生成新表
            DataTable newDt = dt.Clone();
            foreach (int node in treeNodes)
            {
                DataRow[] matchedRows = dt.Select($"Account = {node}");
                if (matchedRows.Length > 0)
                {
                    newDt.ImportRow(matchedRows[0]);
                }
            }
            splitTables.Add(newDt);
        }

        // 输出结果(可以按需保存/使用拆分后的DataTable)
        foreach (DataTable table in splitTables)
        {
            Console.WriteLine("===== 拆分后的子表 =====");
            foreach (DataRow row in table.Rows)
            {
                Console.WriteLine($"Account: {row["Account"]}, Parent: {row["Hierarchy Account"] ?? "None"}");
            }
        }
    }

    static void CollectSubnodes(int node, List<int> nodes, Dictionary<int, List<int>> map)
    {
        nodes.Add(node);
        if (map.ContainsKey(node))
        {
            foreach (int child in map[node])
            {
                CollectSubnodes(child, nodes, map);
            }
        }
    }
}

核心思路总结

不管用哪种语言,解决这类层级拆分问题的核心步骤都是:

  1. 识别根节点:找到所有没有父节点的记录;
  2. 构建父子映射:把每个父节点对应的子节点列表存起来,避免重复查询;
  3. 递归/迭代收集子节点:从每个根节点出发,把所有下属子节点都收集起来,完成拆分。

内容的提问来源于stack exchange,提问作者user2806570

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:19:29