pandas双DataFrame的node_id转换为12位内统一唯一ID的实现方法
问题背景
现有两个pandas DataFrame,结构如下:
df1 node_id lat long 0 [INET_N_855] 53.017810 23.896413 1 [INET_N_1828] 52.984994 22.241386 2 [INET_N_329] 52.881484 20.619795 3 [INET_N_1612] 46.505528 13.592806 4 [INET_N_1009] 46.503733 13.416054 ... ... ... ... 4670 [SEQ_12031_p] 49.697490 12.328040 4671 [NO_N_30] 59.272825 5.519794 4672 [INET_N_379] 35.828836 14.556524 4673 [INET_N_1287] 61.638170 21.398810 4674 [Prod_33] 64.982320 6.611590 [4675 rows x 3 columns] df2 node_id ... long 0 [INET_N_855, INET_N_1828] ... [23.896413, 22.241386] 1 [INET_N_1828, INET_N_329] ... [22.241386, 20.619795] 2 [INET_N_1612, INET_N_1009] ... [13.592806, 13.416054] 3 [INET_N_1612, INET_N_1009] ... [13.592806, 13.416054] 4 [INET_N_1612, INET_N_1009] ... [13.592806, 13.416054] ... ... ... ... 6318 [SEQ_6435_p, INET_N_379] ... [13.88715, 14.556524] 6319 [N_14_M_LMGN, INET_N_1287] ... [23.08042, 21.39881] 6320 [SEQ_12356_p, Prod_33] ... [6.755214, 6.61159] 6321 [N_261_M_LMGN, SEQ_2566_p] ... [25.34835, 25.25854] 6322 [N_261_M_LMGN, SEQ_2566_p] ... [25.34835, 25.25854] [6323 rows x 3 columns]
df2的node_id列元素均由df1的node_id条目组合而成。模拟程序要求单个node_id条目长度≤12字符,需要实现unique_identifier_generator(df1, df2)函数,将df1的node_id转换为符合长度要求的唯一ID,同时按相同映射规则替换df2的node_id对应条目。以下是生成符合要求的唯一ID的可用方案:
推荐实现方案
方案1:自增序列ID(最推荐,无任何冲突风险)
直接用自增数字加简单前缀生成ID,4675条数据最多生成到N4674,长度仅5位,远小于12位限制。
实现代码:
def unique_identifier_generator(df1, df2): # 提取所有唯一的原始node_id unique_nodes = df1['node_id'].unique().tolist() # 生成映射字典,前缀可自定义,只要不超过长度要求即可 id_map = {node: f"N{idx}" for idx, node in enumerate(unique_nodes)} # 以下替换逻辑可自行实现 # df1['new_node_id'] = df1['node_id'].map(id_map) # df2['new_node_id'] = df2['node_id'].apply(lambda x: [id_map[i] for i in x]) return id_map, df1, df2
- 优点:实现简单,100%无冲突,长度完全可控,生成速度极快。
- 缺点:ID本身不携带原节点的语义信息,需要留存映射表用于回溯。
方案2:短哈希ID(无需留存映射表也可反向匹配)
如果需要ID和原字符串直接关联,不需要依赖映射表回溯,可以用哈希算法截断生成短ID。10位的16进制哈希有超过1万亿种组合,几千条数据碰撞概率几乎为0,长度仅10位符合要求。
实现代码:
import hashlib def gen_short_hash(s, length=10): # 用md5生成哈希,取前length位 return hashlib.md5(s.encode('utf-8')).hexdigest()[:length] def unique_identifier_generator(df1, df2): unique_nodes = df1['node_id'].unique().tolist() id_map = {node: gen_short_hash(node) for node in unique_nodes} # 额外做一次唯一性校验,避免极端情况的哈希冲突 assert len(set(id_map.values())) == len(unique_nodes), "哈希冲突,请调整哈希长度" # 替换逻辑自行实现 return id_map, df1, df2
- 优点:不需要留存映射表也可以通过原字符串计算出对应ID,ID随机性强。
- 缺点:无语义信息,极端情况存在冲突可能,需要加一步校验。
方案3:语义缩写ID(可读性最好)
如果原node_id有固定的命名规则,你可以自定义缩写规则保留语义,比如把INET_N_缩写为IN、SEQ_缩写为SQ、Prod_缩写为PR,保留后面的数字部分,生成的ID既短又能看懂对应类型。比如原ID[INET_N_855]缩写为IN855,SEQ_12031_p缩写为SQ12031p,长度都远小于12位。
- 优点:ID可读性强,自带语义,不需要映射表也能识别节点类型。
- 缺点:需要适配原ID的命名规则,通用性稍差。
注意事项
不管用哪种方案,生成映射表后都建议先校验ID的唯一性,以及所有ID长度都≤12,再执行替换操作。
内容的提问来源于stack exchange,提问作者oakca
相关产品推荐
相关产品推荐

