首页 > 解决方案 > 按顺序排列的随机 numpy 数组

问题描述

我有一个随机抽样方法如下:

def costum_random_sample(size):
    randomList = []
    counter = 0
    last_n = -1
    while(size != counter):
        n = random.random()
        if abs(n - last_n) < 0.05:
            continue
        else:
            randomList.append(n)
            counter += 1
            last_n = n

    return np.array(randomList) 

结果是这样的数组([0.50146945, 0.17442673, 0.60011469, 0.13501798])。现在,我想更改它以使其按升序排列。Sort() 在这种情况下不起作用,因为它在生成后更改了我的数组的顺序,并且更改了每个数字之间的逻辑。我希望它按顺序随机排列列表中的数字,这样它可以保持数字序列中的逻辑。我怎样才能做到这一点?

标签: pythonnumpymatrixrandom

解决方案


如果您的数组很短,您可以简单地生成整个数组,对其进行排序,然后拒绝它并重新生成,只要违反了约束即可。

bad = True
while bad:
    arr = np.sort(np.random.rand(size))
    bad = np.any(np.ediff1d(arr) < 0.05)

如果size太大,冲突将太多,这将永远持续,所以只有在有合理的机会随机生成一致的数组时才使用它。请注意,如果size > 20没有符合条件的数组,则将其变为无限循环。

另一种方法是如上所述生成和排序数组,找到不一致的元素对,然后通过增加不一致对之间的距离并从其他位置平均减去此差异来微调数组元素。这不会陷入无限循环,但有更多的数学运算,并且会弯曲均匀分布(尽管我不能告诉你多少)。

编辑经过一番思考,有一个更好的方法。基本上,您需要一个间隔数组,其中有一个固定的间隔符和每个元素之间的一点额外随机性:

random start space
[element1]
0.05 spacer
some more space
[element2]
0.05 spacer
some more space
[element3]
random end space

所有空间需要加起来为 1。但是,其中一些空间是固定的 ( (size - 1) * 0.05);所以如果我们去掉固定的间隔,我们就有了“空间预算”来分配我们的开始、结束和随机空间。所以我们生成随机空间,然后稍微打孔,这样它就可以总结为我们的空间预算。然后添加固定的间隔,累积和会给我们最终的数组(最后还有一个额外1.0的,我们砍掉)。

space_budget = 1 - (size - 1) * 0.05
space = np.random.rand(size + 1)
space *= space_budget / np.sum(space)
space[1:-1] += 0.05
arr = np.cumsum(space)[:-1]

对于size = 21,您每次只得到一个解,space_budget为零。对于较大的size,您开始超出 0...1 范围,因为在数学上不可能将超过 21 个 0.05 垫片塞入该区间。


推荐阅读