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

如何在Python中基于person与associate关联生成分组列?

在Python中基于人员关联关系创建分组列

这个问题本质是图论中的连通分量问题:把每个人员看作节点,person和associate的关联关系看作节点间的边,所有能通过直接/间接关联连起来的人员属于同一组。下面提供两种实用的实现方式:


方法一:用NetworkX库(简单快捷)

NetworkX是Python的图论工具库,能快速处理连通分量问题,适合大多数场景。

代码示例:

import pandas as pd
import networkx as nx

# 构造示例数据(实际中可替换为pd.read_csv读取你的数据)
data = pd.DataFrame({
    'index': [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3],
    'person': ['name1','name1','name1','name2','name2','name2','name3','name3','name3','name4','name4','name4','name5','name5','name5'],
    'associate': ['-','-','-','name1','name4','name3','-','-','-','-','-','-','-','-','-']
})

# 替换缺失标记为NaN,过滤无效关联行
data['associate'] = data['associate'].replace('-', pd.NA)
valid_edges = data.dropna(subset=['associate'])[['person', 'associate']]

# 创建无向图并添加节点、边
graph = nx.Graph()
all_people = pd.concat([data['person'], data['associate'].dropna()]).unique()
graph.add_nodes_from(all_people)
graph.add_edges_from(valid_edges.values)

# 给每个连通分量分配组ID
group_dict = {}
current_group = 1
for component in nx.connected_components(graph):
    for person in component:
        group_dict[person] = current_group
    current_group += 1

# 映射组ID到原数据,无关联人员留空(或改为单独分组)
data['group'] = data['person'].map(group_dict)

# 可选:给无关联人员分配单独组
# last_group = current_group - 1
# data['group'] = data['group'].fillna(data['person'].rank(method='dense') + last_group)

print(data)

方法二:手动实现并查集(无需额外库)

如果不能安装第三方库,可以用**并查集(Union-Find)**数据结构手动实现,这是处理连通分量的经典算法。

代码示例:

import pandas as pd

# 实现并查集类
class UnionFind:
    def __init__(self):
        self.parent = {}
    
    # 查找节点的根节点(路径压缩优化)
    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    
    # 合并两个节点所在的集合
    def union(self, x, y):
        if x not in self.parent:
            self.parent[x] = x
        if y not in self.parent:
            self.parent[y] = y
        root_x = self.find(x)
        root_y = self.find(y)
        if root_x != root_y:
            self.parent[root_y] = root_x

# 构造示例数据
data = pd.DataFrame({
    'index': [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3],
    'person': ['name1','name1','name1','name2','name2','name2','name3','name3','name3','name4','name4','name4','name5','name5','name5'],
    'associate': ['-','-','-','name1','name4','name3','-','-','-','-','-','-','-','-','-']
})

# 处理缺失值
data['associate'] = data['associate'].replace('-', pd.NA)
valid_edges = data.dropna(subset=['associate'])[['person', 'associate']]

# 初始化并查集,合并所有关联对
uf = UnionFind()
for _, row in valid_edges.iterrows():
    uf.union(row['person'], row['associate'])

# 给每个人员分配组ID
group_dict = {}
current_group = 1
all_people = pd.concat([data['person'], data['associate'].dropna()]).unique()

# 先处理有关联的人员
for person in all_people:
    if person in uf.parent:
        root = uf.find(person)
        if root not in group_dict:
            group_dict[root] = current_group
            current_group += 1
        group_dict[person] = group_dict[root]

# 给无关联人员分配单独组
for person in data['person'].unique():
    if person not in group_dict:
        group_dict[person] = current_group
        current_group += 1

# 映射到原数据
data['group'] = data['person'].map(group_dict)

print(data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:22:03