如何为DataFrame跨两列匹配分配组编号(不考虑顺序)
问题描述
现有如下DataFrame,需基于两列间共享的值(含间接关联,不考虑顺序)为数据分配组编号:
示例代码
import pandas as pd data = [[1, 10], [1, 15], [0, 15], [4, 0], [2, 3]] df = pd.DataFrame(data, columns=['Value_1', 'Value_2'])
原始数据
| Value_1 | Value_2 |
|---|---|
| 1 | 10 |
| 1 | 15 |
| 0 | 15 |
| 4 | 0 |
| 2 | 3 |
期望输出
需新增Group列,结果如下:
| Value_1 | Value_2 | Group |
|---|---|---|
| 1 | 10 | 1 |
| 1 | 15 | 1 |
| 0 | 15 | 1 |
| 4 | 0 | 1 |
| 2 | 3 | 2 |
分组规则
- 若某值在任意行的
Value_1或Value_2中出现,且与另一行的某个值存在直接/间接关联,则这些行属于同一组。 - 例:1、10、15、0、4通过关联共享属于组1;2和3未与其他值关联,单独为组2。
解决方案
这个问题本质是寻找图的连通分量:把每个数值当作节点,每行的两个数值之间建立一条边,同一连通分量里的节点对应的行就属于同一组。可以用networkx库实现:
步骤1:安装依赖(若未安装)
pip install networkx
步骤2:代码实现
import pandas as pd import networkx as nx # 构造数据 data = [[1, 10], [1, 15], [0, 15], [4, 0], [2, 3]] df = pd.DataFrame(data, columns=['Value_1', 'Value_2']) # 创建无向图并添加边 G = nx.Graph() G.add_edges_from(df[['Value_1', 'Value_2']].values) # 获取每个节点所属的连通分量,映射为组编号 components = list(nx.connected_components(G)) node_to_group = {} for idx, comp in enumerate(components, 1): for node in comp: node_to_group[node] = idx # 为每行分配组编号:同一行的两个节点必在同一组,取任意一列映射即可 df['Group'] = df['Value_1'].map(node_to_group) print(df)
输出结果
Value_1 Value_2 Group 0 1 10 1 1 1 15 1 2 0 15 1 3 4 0 1 4 2 3 2
原理说明
- 构建无向图:每行的两个值作为一条边,把所有相关联的值连接成一个连通分量。
- 遍历连通分量:给每个连通分量分配唯一的组编号,再把每个数值映射到对应的组。
- 映射回DataFrame:用任意一列的值匹配组编号,同一行的两个值必然属于同一个连通分量,结果一致。
内容的提问来源于stack exchange,提问作者SMar3552
相关产品推荐
相关产品推荐

