Pandas如何基于groupby与传递性规则实现交易地址聚类
这个场景不需要手动逐组遍历校验传递关系,本质是无向图连通分量检测问题,用图算法或者并查集可以直接实现,逻辑天然覆盖你提到的两条聚类规则。
核心逻辑
把每个地址视为无向图的节点,同一笔交易内的所有地址属于直接关联的节点,最终所有互相连通的节点自动构成一个地址簇,传递性会在连通关系计算时自动生效,不需要额外写判断逻辑。
可直接运行的实现方案
先构造示例测试数据:
import pandas as pd from itertools import combinations import networkx as nx df = pd.DataFrame({ 'TX_ID': [1,2,2,1,2,3], 'Address': ['address2','address3','address1','address1','address4','address50'] })
方案1:NetworkX图计算(代码最简洁,适合中小规模数据)
直接用图计算库的现成连通分量接口,代码量最少:
# 初始化无向图 G = nx.Graph() # 按交易ID分组,为同交易地址建立关联 for _, addr_group in df.groupby('TX_ID')['Address']: addr_list = addr_group.unique() if len(addr_list) == 1: G.add_node(addr_list[0]) else: # 同一交易下的地址两两建立连边 G.add_edges_from(combinations(addr_list, 2)) # 提取连通分量,即最终地址簇 clusters = list(nx.connected_components(G))
运行得到的clusters和预期结果完全匹配:
[{'address1', 'address2', 'address3', 'address4'}, {'address50'}]
方案2:原生并查集实现(性能更高,适合百万级以上大数据量)
如果数据量很大,不想依赖图计算库,可以自己实现轻量的并查集(不相交集合)结构,内存占用和运行速度都更优:
class UnionFind: def __init__(self): self.parent = dict() def find_root(self, node): # 路径压缩优化 if self.parent[node] != node: self.parent[node] = self.find_root(self.parent[node]) return self.parent[node] def merge(self, a, b): # 初始化新节点 if a not in self.parent: self.parent[a] = a if b not in self.parent: self.parent[b] = b root_a = self.find_root(a) root_b = self.find_root(b) if root_a != root_b: self.parent[root_b] = root_a uf = UnionFind() # 遍历每个交易的地址组,合并同组地址 for _, addr_group in df.groupby('TX_ID')['Address']: addr_list = addr_group.unique() first_addr = addr_list[0] for addr in addr_list[1:]: uf.merge(first_addr, addr) # 按根节点聚合得到所有簇 cluster_dict = dict() for addr in uf.parent: root = uf.find_root(addr) if root not in cluster_dict: cluster_dict[root] = [] cluster_dict[root].append(addr) clusters = list(cluster_dict.values())
结果格式化
如果需要输出示例里的标注格式,直接遍历打印即可:
for idx, cluster in enumerate(clusters, 1): print(f"CLUSTER{idx}: {sorted(cluster)}")
输出:
CLUSTER1: ['address1', 'address2', 'address3', 'address4'] CLUSTER2: ['address50']
两种方案都不需要手动编写多层循环校验跨交易的地址传递关系,只要把同交易的地址做关联,算法会自动把所有存在关联路径的地址归为同一个簇,哪怕地址跨越多笔交易也能正确识别。
内容的提问来源于stack exchange,提问作者Random Student
相关产品推荐
相关产品推荐

