Python中DataFrame内双向关联值的分组映射实现问题
解决方案:用图论识别连通分量实现分组
你遇到的问题本质是要找出无向图中的连通分量——把每个数值看作图的节点,每一行的两个数值之间是一条双向的关联边,所有能通过边直接或间接连起来的节点就属于同一个分组。之前只遍历单行的方式只能处理直接关联,没法覆盖跨多行的间接关联,用图论工具就能完美解决这个问题。
具体实现步骤(Python)
我们可以用pandas处理数据,配合networkx库来构建图并识别连通分量:
- 导入所需库
import pandas as pd import networkx as nx
- 定义输入数据
input_data = [[1000, 1002], [1002, 1003], [1004, 1000],[1010,1050],[1060,1002],[1050,1100],[1200,1250],[1300,1200]] input_df = pd.DataFrame(input_data, columns=['Value1', 'Value2'])
- 构建无向图
因为我们的关联是双向的(Value1关联Value2等价于Value2关联Value1),所以创建无向图来建模:
# 初始化无向图 G = nx.Graph() # 将每一行的两个数值作为一条边添加到图中 G.add_edges_from(input_df.values)
- 识别连通分量并分配组索引
找出图中所有的连通子图,每个子图对应一个分组,给每个分组分配从1开始的有序索引:
# 获取所有连通分量,按组内最小节点排序(可选,让分组结果更规整) connected_components = sorted(nx.connected_components(G), key=lambda x: min(x)) # 创建"数值→组索引"的映射字典 node_to_group = {} for group_idx, component in enumerate(connected_components, start=1): for node in component: node_to_group[node] = group_idx
- 生成最终输出格式
根据用户需求,我们需要保留输入中所有出现过的数值(包括重复项),并对应到各自的组索引:
# 把输入的Value1和Value2所有元素合并成一个序列(保留重复) all_values = pd.concat([input_df['Value1'], input_df['Value2']], ignore_index=True) # 生成结果DataFrame result_df = pd.DataFrame({ 'Index': all_values.map(node_to_group), 'Value': all_values }) # 打印结果 print(result_df)
运行结果
这段代码会输出和你期望完全一致的格式:
Index Value 0 1 1000 1 1 1002 2 1 1002 3 1 1003 4 1 1004 5 1 1000 6 2 1010 7 2 1050 8 1 1060 9 1 1002 10 2 1050 11 2 1100 12 3 1200 13 3 1250 14 3 1300 15 3 1200
(注:如果需要去掉重复的数值行,可以对result_df使用drop_duplicates(),但根据你的期望输出,保留重复项更符合需求)
为什么这个方法有效?
- 无向图的建模完美匹配了"双向关联"的需求,不管是Value1指向Value2还是反过来,都会被视为同一条边。
- 连通分量的识别会自动把所有直接/间接关联的数值归为一组,比如1004→1000→1002→1003→1060这些数值会被全部纳入同一组,完全解决了跨多行关联的问题。
内容的提问来源于stack exchange,提问作者Karthick Mohanraj
相关产品推荐
相关产品推荐

