Python 带约束的numpy洗牌
我想洗牌一个一维numpy数组,约束条件是没有任何元素与来自另一个相同形状数组的相应元素(即相同索引)匹配。可以假设每个数组的所有元素都是唯一的 比如说,Python 带约束的numpy洗牌,python,arrays,numpy,Python,Arrays,Numpy,我想洗牌一个一维numpy数组,约束条件是没有任何元素与来自另一个相同形状数组的相应元素(即相同索引)匹配。可以假设每个数组的所有元素都是唯一的 比如说, a = np.arange(10) b = a.copy() np.random.shuffle(b) np.where(a==b) # This should be empty 最好的办法是什么?有什么想法吗?根据乔治的回答改编 你可以试着一次又一次地重新洗牌,直到你的条件得到满足。这被称为a。对于大的n,列表的随机排列没有固定点的概率大
a = np.arange(10)
b = a.copy()
np.random.shuffle(b)
np.where(a==b) # This should be empty
最好的办法是什么?有什么想法吗?根据乔治的回答改编
你可以试着一次又一次地重新洗牌,直到你的条件得到满足。这被称为a。对于大的
n
,列表的随机排列没有固定点的概率大约为1/e,因此在运气好之前可以安全地进行重新排列。另一方面,给出了一种产生混乱的算法。在基准测试方面,这显然是最快的@Christopher的运行速度为:5.85 ms±455µs/循环(平均值±标准偏差为7次运行,每个循环100次)
,而这一速度为72.2µs±12.8µs/循环(平均值±标准偏差为7次运行,每个循环100次)
因此,在测试2000次排列时,平均快98%。
def random_derangement(n):
while True:
v = np.arange(n)
for j in np.arange(n - 1, -1, -1):
p = np.random.randint(0, j+1)
if v[p] == j:
break
else:
v[j], v[p] = v[p], v[j]
else:
if v[0] != 0:
return v
def random_derangement(N):
original = np.arange(N)
new = np.random.permutation(N)
same = np.where(original == new)[0]
while len(same) != 0:
swap = same[np.random.permutation(len(same))]
new[same] = new[swap]
same = np.where(original == new)[0]
if len(same) == 1:
swap = np.random.randint(0, N)
new[[same[0], swap]] = new[[swap, same[0]]]
return new