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

如何用Python复刻D3.stratify式新冠病毒谱系层级树结构?

解决新冠病毒谱系树层级构建问题的几种方法

方法1:拆分谱系路径,逐层定位父节点

针对每个谱系名称(如BA.1.1),按.拆分出完整的层级路径列表(['BA', 'BA.1', 'BA.1.1']),从根节点开始逐层遍历路径,找到对应父节点后再添加子节点,自动形成正确的层级关系。

示例代码思路:

class LineageNode:
    def __init__(self, name):
        self.name = name
        self.children = {}  # 用字典存子节点,快速查找

class LineageTree:
    def __init__(self):
        self.root = LineageNode("root")  # 可根据数据集调整为顶级谱系节点

    def add_lineage(self, lineage_name):
        parts = lineage_name.split('.')
        current_node = self.root
        current_path = []
        for part in parts:
            current_path.append(part)
            full_path = '.'.join(current_path)
            # 不存在则创建节点并添加为当前节点的子节点
            if full_path not in current_node.children:
                current_node.children[full_path] = LineageNode(full_path)
            # 移动到当前路径节点,继续处理下一层
            current_node = current_node.children[full_path]

使用这个逻辑,BA.1.1会先关联到BA节点,再在BA下找到/创建BA.1,最后将BA.1.1添加为BA.1的子节点。

方法2:预构建父节点映射表

先遍历所有谱系名称,为每个节点生成对应的父节点名称(比如BA.1.1的父节点是BA.1,BA.1的父节点是BA),再按层级深度排序添加节点,确保父节点先于子节点被创建。

步骤及示例代码:

# 示例数据集
all_lineages = ["BA", "BA.1", "BA.1.1", "BA.2"]
parent_map = {}

# 生成父节点映射字典
for lineage in all_lineages:
    if '.' in lineage:
        parent = '.'.join(lineage.split('.')[:-1])
        parent_map[lineage] = parent
    else:
        parent_map[lineage] = "root"  # 顶级节点的父节点设为根

# 构建树结构
nodes = {"root": LineageNode("root")}
# 按层级深度排序,确保先添加父节点
for lineage in sorted(all_lineages, key=lambda x: len(x.split('.'))):
    if lineage not in nodes:
        nodes[lineage] = LineageNode(lineage)
    parent_name = parent_map[lineage]
    nodes[parent_name].children[lineage] = nodes[lineage]

方法3:修改现有add_to_tree方法逻辑

如果要保留原有Lineage类,只需修改add_to_tree方法,拆分谱系路径并找到正确的父节点,而非直接添加到根节点:

class Lineage:
    def __init__(self, name):
        self.name = name
        self.children = []

def add_to_tree(root, lineage_name):
    parts = lineage_name.split('.')
    current = root
    # 逐层定位父节点
    for i in range(len(parts)-1):
        parent_path = '.'.join(parts[:i+1])
        # 在当前节点的子节点中查找父节点
        found = None
        for child in current.children:
            if child.name == parent_path:
                found = child
                break
        if found:
            current = found
        else:
            # 父节点不存在则先创建
            new_node = Lineage(parent_path)
            current.children.append(new_node)
            current = new_node
    # 添加当前谱系节点
    new_node = Lineage(lineage_name)
    current.children.append(new_node)

调用add_to_tree(root, "BA.1.1")时,会自动将节点挂载到BA.1下,而非直接作为BA的子节点。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:55:20