Python中的顺序随机选择

时间:2018-02-24 13:08:30

标签: python numpy

我想从数组中随机选择,但要求是输出数组的元素将增加1(并从零开始)。例如,如果我想在0到5之间得到5个数字,那么可以做

np.random.choice(np.arange(6), 5)
array([5, 0, 5, 2, 5])

在这种情况下,我希望这样:

array([2, 0, 2, 1, 2])

另一个例子,如果

np.random.choice(np.arange(6), 5)
array([1, 1, 1, 4, 2])

我试图以“

”的方式“改变”这一点
array([0, 0, 0, 2, 1])

最后的例子......选择0到5之间的15个数字

np.random.choice(np.arange(6), 15)
array([4, 5, 3, 0, 4, 5, 3, 0, 2, 5, 2, 3, 2, 4, 4])

最终我想以

结束
array([3, 4, 2, 0, 3, 4, 2, 0, 1, 4, 1, 2, 1, 3, 3])

3 个答案:

答案 0 :(得分:3)

您要做的是将原始数组x中的每个条目替换为x的唯一元素数组中的 index (按排序顺序) 。例如,如果xnp.array([7, 6, 2, 7, 7, 2]),则x的唯一元素为[2, 6, 7],我们希望将每个数字替换为其在该唯一元素数组中的位置:是,将每个2替换为0,将每个6替换为1,将每个7替换为2

numpy.unique函数执行这两项任务:它为您找到(排序的)唯一元素数组,如果您通过return_inverse=Truenp.unique 也将给你一个第二个返回值,它包含你所追求的索引。所以你需要做的就是用np.unique调用return_inverse=True,扔掉第一个返回值,然后保留第二个返回值。例子:

>>> import numpy as np
>>> np.unique([5, 0, 5, 2, 5], return_inverse=True)[1]
array([2, 0, 2, 1, 2])
>>> x = np.array([4, 5, 3, 0, 4, 5, 3, 0, 2, 5, 2, 3, 2, 4, 4])
>>> np.unique(x, return_inverse=True)[1]
array([3, 4, 2, 0, 3, 4, 2, 0, 1, 4, 1, 2, 1, 3, 3])

答案 1 :(得分:2)

你可以做的是从一个随机选择的数组开始

x = np.random.choice(np.arange(6), 5)

然后收集唯一值并对其进行排序

v = sorted(set(x))

然后将原始值映射到v中的索引:

result = [v.index(y) for y in x]

答案 2 :(得分:0)

如果您的原始序列仅包含唯一元素,那么基于排序的方法(如np.unique)在O(n log n)实际上有点浪费,因为O(n)解可用(假设n> = k,其中k是可供选择的集合的大小):

>>> import numpy as np
>>>
to_choose_from = [1, 5, 7, 9, 10, 'hello', ()]
>>> n = 12
>>> 
>>> k = len(to_choose_from)
# make sure no duplicates - skip this if you happen to know
>>> assert len(set(to_choose_from)) == k
>>> 
>>> chc = np.random.randint(0, k, (n,))
>>> chc
array([4, 4, 1, 5, 3, 1, 5, 5, 6, 1, 6, 6])
>>> 
>>> occur = np.zeros((k,), int)
>>> occur[chc] = 1
>>> idx, = np.where(occur)
>>> occur[idx] = np.arange(idx.size)
>>> result = occur[chc]
>>> result
array([2, 2, 0, 3, 1, 0, 3, 3, 4, 0, 4, 4])