Python 用另一个数组中的随机元素填充numpy数组
我不确定这是否可行,但事情是这样的。假设我有一个数组:Python 用另一个数组中的随机元素填充numpy数组,python,numpy,Python,Numpy,我不确定这是否可行,但事情是这样的。假设我有一个数组: array1 = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1] 现在我想创建一个numpy1d数组,由5个元素组成,这些元素是从数组1中随机抽取的,条件是总和等于1。例如,一个看起来像[.2、.2、.2、.1、.1]的numpy数组 目前我使用的是随机模块和选择函数,如下所示: range1=np.array([choice(array1)、choice(array1)、choice(array1)、choice(a
array1 = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1]
现在我想创建一个numpy1d数组,由5个元素组成,这些元素是从数组1中随机抽取的,条件是总和等于1。例如,一个看起来像[.2、.2、.2、.1、.1]
的numpy数组
- 目前我使用的是随机模块和选择函数,如下所示:
然后检查range1是否符合标准;我想知道是否有更快的方法,类似于range1=np.array([choice(array1)、choice(array1)、choice(array1)、choice(array1)])
randomArray=np.random.random()
- 如果我能将这个数组存储在某个库中,这样更好,如果我尝试生成100个这样的数组,就不会重复,但这不是必需的
- 不久前我也不得不做类似的事情
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
如果使用numpy 1.7.0+,则可以使用:
>>> 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])
要得到5个元素的和等于1
- 生成4个随机数
- 从1->x中减去4个数字的总和
- 如果数组1中包含x,则将其用作最终数字;还是重复
另一个版本(假设给定数组已排序):
EPS=0.0000001
def解算(arr,总计,n):
尽管如此:
xs=np.随机选择(arr,n-1)
t=xs.sum()
i=平均值(总计-t)
如果abs(t+arr[i]-总计)
如果您不关心输出序列中值的顺序,那么列表中5个值组合加起来等于1的数量非常少。但在您建议的特定情况下,计算起来有点复杂,因为浮点值存在舍入问题。如果您使用一组整数(例如range(11)
)并找到加起来等于10的组合,则可以更轻松地解决此问题。如果需要分数,只需将结果中的值除以10即可
无论如何,这里有一个生成器,它可以生成所有可能的集合,这些集合相加为给定的值:
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
您可以随机选择其中一个(使用random.choice
),或者如果您计划使用其中的许多,并且不想重复,您可以使用random.shuffle
,然后迭代
results = list(picks(range(11), 5, 10))
random.shuffle(results)
for r in results:
# do whatever you want with r
将值添加到1的约束极大地限制了有效的选择。允许复制吗?如果不是,唯一有效的选择是
[0、.1、.2、.3、.4]
,加起来应该接近1
(如果不小心,浮点舍入可能会导致问题)。如果允许重复,那么就有不止一个选项,问题也不是很简单。如果您已经在使用numpy,为什么不直接使用numpy.random.choice(source,n,False)
?@Blckknght我以前没有听说过这个函数,但我认为您是对的-这样做更容易。high
for是独占的。你应该通过len(index)
来代替。我也在使用类似这样的东西,它似乎在range1=1.0*(np.random.random_integers(1,10,size=(1,5)))/10HI-Blckknght:这很有效-我不理解它是如何工作的,但会研究它以了解更多。非常感谢。该算法类似于给定一组硬币面额对特定值进行更改的算法。然而,在本例中,我并没有试图用最少的硬币进行兑换,而是试图准确地挑选n
项,这些项加起来就是target
。第一个if
是基本情况,只剩下一个值可供选择。如果列表中有可用的目标值,我们选择它!循环是递归的情况,在这种情况下,您选择一个值,然后递归以找到一个较小的集合,该集合与值的其余部分相加?如果我还想要序列(0,0,0,1,9)以及(9,1,0,0,0),那么?谢谢。@AlexLee:这很复杂。您希望结果序列的每个唯一排列都具有相同的可能性吗?如果是这样的话,像(2,2,2,2,2)
这样只有一个唯一排列的解决方案将比(0,0,0,0,10)
的五个唯一排列或(0,0,0,1,9)
的20个唯一排列少得多。如果您从递归步骤中删除切片,我的生成器就可以做到这一点:用于r in picks(值,n-1,target-v):
(如果需要,您也可以取消枚举
调用)。但是,这会产生大约33倍的结果(并且可能需要更多的时间)!谢谢Blckknght-你真是不可思议-像你这样的人让互联网变得很棒。由于浮点舍入,此解决方案可能存在问题。它永远不会产生[0.2,0.2,0.2,0,0.4]
(按顺序),因为当你计算1-(0.2+0.2+0.2)
时,你得到的是0.399999999999999
,而不是0.4
。(这就是为什么我的解决方案使用整数:-)。我也不确定这个算法是否能生成均匀分布的解。也就是说,我实际上不知道如何确定它产生的分布,所以它可能比我想象的要好。
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
>>> 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)
results = list(picks(range(11), 5, 10))
random.shuffle(results)
for r in results:
# do whatever you want with r