Pandas为DataFrame中无序值对分配从1开始的唯一编号
问题:为Pandas DataFrame的无序值对分配唯一编号
我有一个包含a和b两列的Pandas DataFrame,需要新增一列no,为无序值对分配从1开始的唯一编号:若值对元素相同(顺序可不同)则编号一致;遇到新值对(至少一个元素未出现过)或唯一值对时,编号递增。
示例效果如下:
| a | b | no |
|---|---|---|
| 1 | 2 | 1 |
| 4 | 3 | 2 |
| 2 | 1 | 1 |
| 3 | 4 | 2 |
| 5 | 6 | 3 |
| 4 | 7 | 4 |
我已经写出了可行代码,但想找更简洁高效的实现:
l = [] n = 1 nums = {} for a, b in zip(df.a, df.b): s = str(sorted([a, b])) if s in nums.keys(): l.append(nums[s]) else: nums[s] = n l.append(n) n += 1 df['no'] = l
更简洁高效的解决方案
方法1:apply+factorize(简洁易读)
通过apply对每行的a、b值排序生成唯一标识,再用factorize快速生成编号:
import pandas as pd # 对每行的a、b排序后转为元组(元组可哈希,适合作为factorize的输入) sorted_pairs = df[['a', 'b']].apply(lambda row: tuple(sorted(row)), axis=1) # factorize返回的第一个元素是从0开始的编码,加1得到从1开始的编号 df['no'] = pd.factorize(sorted_pairs)[0] + 1
方法2:numpy向量化排序(性能最优)
如果处理的数据集很大,用numpy的向量化排序替代逐行apply,速度会更快:
import pandas as pd import numpy as np # 对a、b列组成的二维数组按行排序 sorted_array = np.sort(df[['a', 'b']].values, axis=1) # 转换为元组数组(保证可哈希) sorted_pairs = [tuple(row) for row in sorted_array] # 生成编号 df['no'] = pd.factorize(sorted_pairs)[0] + 1
方案优势
- 避免了Python循环的开销,利用Pandas/numpy的向量化操作提升效率,数据量越大优势越明显
- 代码更简洁,逻辑清晰,易于维护
内容的提问来源于stack exchange,提问作者something-original
相关产品推荐
相关产品推荐

