我不确定这是否可行但是这里有。假设我有一个数组:
array1 = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1]
现在我想创建一个numpy 1D数组,由5个元素组成,这些元素是从array1中随机抽取的,条件是sum等于1.例如,类似于n {{1}的numpy数组}}。
目前我使用随机模块和选择函数,如下所示:
[.2,.2,.2,.1,.1]
然后检查range1以查看它是否符合标准;我想知道是否有更快的方式,类似的东西
而是range1= np.array([choice(array1),choice(array1),choice(array1),choice(array1),choice(array1)])
。
如果我可以将这个数组存储在某个库中会更好,这样如果我尝试生成100个这样的数组,那就没有重复,但这不是必需的。
答案 0 :(得分:5)
如果你使用numpy 1.7.0 +:
,你可以使用numpy.random.choice
>>> import numpy as np
>>> array1 = np.array([0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1])
>>> np.random.choice(array1, 5)
array([ 0. , 0. , 0.3, 1. , 0.3])
>>> np.random.choice(array1, 5, replace=False)
array([ 0.6, 0.8, 0.1, 0. , 0.4])
要获得总和等于1的5个元素,
>>> import numpy as np
>>>
>>> def solve(arr, total, n):
... while True:
... xs = np.random.choice(arr, n-1)
... remain = total - xs.sum()
... if remain in arr:
... return np.append(xs, remain)
...
>>> array1 = np.array([0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1])
>>> print solve(array1, 1, 5)
[ 0.1 0.3 0.4 0.2 0. ]
另一个版本(假设给定数组已排序):
EPS = 0.0000001
def solve(arr, total, n):
while True:
xs = np.random.choice(arr, n-1)
t = xs.sum()
i = arr.searchsorted(total - t)
if abs(t + arr[i] - total) < EPS:
return np.append(xs, arr[i])
答案 1 :(得分:2)
我不得不做一些类似的事情。
def getRandomList(n, source):
'''
Returns a list of n elements randomly selected from source.
Selection is done without replacement.
'''
list = source
indices = range(len(source))
randIndices = []
for i in range(n):
randIndex = indices.pop(np.random.randint(0, high=len(indices)))
randIndices += [randIndex]
return [source[index] for index in randIndices]
data = [1,2,3,4,5,6,7,8,9]
randomData = getRandomList(4, data)
print randomData
答案 2 :(得分:2)
如果您不关心输出序列中值的顺序,则列表中加起来为1的值的5值组合的数量非常小。在您提出的特定情况下,计算起来有点复杂,因为浮点值具有舍入问题。如果使用一组整数(例如range(11)
)并找到加起来为10的组合,则可以更轻松地解决问题。然后,如果需要小数值,只需将结果中的值除以10。 / p>
无论如何,这是一个生成器,它可以产生所有可能的集合,这些集合可以累加给定值:
def picks(values, n, target):
if n == 1:
if target in values:
yield (target,)
return
for i, v in enumerate(values):
if v <= target:
for r in picks(values[i:], n-1, target-v):
yield (v,)+r
以下是数字0到10的结果:
>>> for r in picks(range(11), 5, 10):
print(r)
(0, 0, 0, 0, 10)
(0, 0, 0, 1, 9)
(0, 0, 0, 2, 8)
(0, 0, 0, 3, 7)
(0, 0, 0, 4, 6)
(0, 0, 0, 5, 5)
(0, 0, 1, 1, 8)
(0, 0, 1, 2, 7)
(0, 0, 1, 3, 6)
(0, 0, 1, 4, 5)
(0, 0, 2, 2, 6)
(0, 0, 2, 3, 5)
(0, 0, 2, 4, 4)
(0, 0, 3, 3, 4)
(0, 1, 1, 1, 7)
(0, 1, 1, 2, 6)
(0, 1, 1, 3, 5)
(0, 1, 1, 4, 4)
(0, 1, 2, 2, 5)
(0, 1, 2, 3, 4)
(0, 1, 3, 3, 3)
(0, 2, 2, 2, 4)
(0, 2, 2, 3, 3)
(1, 1, 1, 1, 6)
(1, 1, 1, 2, 5)
(1, 1, 1, 3, 4)
(1, 1, 2, 2, 4)
(1, 1, 2, 3, 3)
(1, 2, 2, 2, 3)
(2, 2, 2, 2, 2)
您可以随机选择其中一个(使用random.choice
),或者如果您打算使用其中的许多并且您不想重复自己,则可以使用random.shuffle
,然后迭代
results = list(picks(range(11), 5, 10))
random.shuffle(results)
for r in results:
# do whatever you want with r