如何高效查找含重复行对的二维数组的唯一行全排列?
高效获取数组的唯一行全排列
针对你遇到的问题——原先生成全量行排列再去重效率极低的情况,完全可以通过先分组重复行,再生成位置分配方案的方式,直接得到所有唯一行全排列,无需生成冗余的重复排列。
核心思路
数组中存在重复行时,交换相同行的位置不会产生新的唯一排列。因此我们可以:
- 先识别数组中的所有唯一行,以及每类行的重复次数;
- 通过组合方式为每类唯一行分配对应数量的位置;
- 根据位置分配结果填充行数据,直接生成唯一排列。
代码实现
import numpy as np from itertools import combinations # 定义目标数组 arr = np.array([[1, 2, 3, 4], [3, 3, 3, 6], [2, 0, 0, 2], [2, 0, 0, 2], [8, 2, 8, 2], [4, 5, 4, 5], [3, 3, 3, 6], [4, 5, 4, 5], [0, 9, 8, 7], [1, 2, 3, 4]]) # 提取唯一行及对应重复次数 unique_rows, counts = np.unique(arr, axis=0, return_counts=True) total_rows = len(arr) unique_perms = [] # 递归生成位置分配方案 def generate_pos_assignments(count_list, remaining_pos): if not count_list: yield [] return current_count = count_list[0] # 为当前唯一行选对应数量的位置 for pos_comb in combinations(remaining_pos, current_count): remaining = [p for p in remaining_pos if p not in pos_comb] # 递归处理剩余行的位置分配 for sub_assign in generate_pos_assignments(count_list[1:], remaining): yield [pos_comb] + sub_assign # 遍历所有位置分配,生成唯一排列 for assignment in generate_pos_assignments(counts.tolist(), list(range(total_rows))): permutation = np.empty((total_rows, arr.shape[1]), dtype=arr.dtype) for row_idx, pos_group in enumerate(assignment): permutation[list(pos_group)] = unique_rows[row_idx] unique_perms.append(permutation) # 转换为numpy数组格式 unique_perms = np.array(unique_perms)
优势说明
这种方法直接生成理论上的唯一排列总数(示例中为 10!/(2^4) = 226800),完全避免了生成10!(3628800)个冗余排列的巨大计算开销,效率提升非常明显。
内容的提问来源于stack exchange,提问作者user109387
相关产品推荐
相关产品推荐

