如何快速生成满足成对结构要求的Python数组排列?
高效生成符合要求的Python数组方案
需求说明
- 目标数组第一列为1到42的连续数字;
- 第二列由21个1和21个3组成,需按连续两两分组,每组只能是
[1,3]或[3,1](禁止[1,1]或[3,3]的分组)。
原方案问题
原代码通过反复洗牌+分组验证的方式实现,完全依赖随机概率,效率极低(曾耗时711799次洗牌才得到合法结果);尝试np.tile方法因42无法被4整除,无法直接复用固定模式。
原代码
import numpy as np import random trials=np.linspace(1,42,42) vec1=np.ones(21) vec2=vec1+2 trial_types=np.concatenate((vec1,vec2)) isok=0 numb_run=1 while isok == 0: random.shuffle(trial_types) break_con = 0 i=1 while i <= len(trial_types): if trial_types[i] == trial_types[i - 1]: break_con = 1 if break_con == 1: break i +=2 numb_run+=1 if break_con == 0: isok=1 print(trial_types) print(numb_run)
高效实现方案
直接构造合法分组再打乱,无需随机验证,一步生成符合要求的第二列:
思路
每组[1,3]或[3,1]都恰好包含1个1和1个3,21组刚好消耗21个1和21个3,完全匹配数量要求。只需:
- 生成指定数量的两种合法分组;
- 打乱分组顺序;
- 将分组展开为一维数组。
代码实现
import numpy as np import random # 第一列:1到42的连续数字 trials = np.arange(1, 43) # 比linspace更高效的整数生成方式 # 构造第二列:生成合法分组并打乱 pair1 = [1, 3] pair2 = [3, 1] # 随机选择两种分组的数量,总数为21组 pair1_count = random.randint(0, 21) pair2_count = 21 - pair1_count # 生成分组列表 pairs = [pair1]*pair1_count + [pair2]*pair2_count # 打乱分组顺序 random.shuffle(pairs) # 展开为一维数组 trial_types = np.array(pairs).flatten() # 组合成最终二维数组 result = np.column_stack((trials, trial_types)) print(result)
说明
- 两种分组的数量可以任意调整,只要总数为21组即可;
- 用
random.randint生成分组比例,能保证每次结果的随机性; - 该方法时间复杂度为O(n),无需循环验证,效率远超原方案。
示例输出(第二列)
[3. 1. 3. 1. 3. 1. 1. 3. 1. 3. 3. 1. 1. 3. 1. 3. 3. 1. 3. 1. 3. 1. 1. 3. 3. 1. 1. 3. 3. 1. 1. 3. 3. 1. 3. 1. 3. 1. 3. 1. 3. 1.]
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

