2016-01-02 61 views
3

我试图在条件为True时得到一个随机选择的数字序列。numpy中的随机值

我有一个与NumPy阵列全布尔数字:

In [1]: multiples 
Out[1]: array([False, False, False, True, True, False, False, False, False, 
       False, False, False, False, False, False, False, False, False, 
       False, False, False, False, False, False, False, False, False, 
       False, False, True, True, True, True, False, False, False, 
       False, False, False, True, True, False, True, True, False, 
       False, False, False, True, True, False, False, False, False, 
       False, False, False, False, False, False, False, False, False, 
       False, False, False, False, False, False, False, False, False, 
       False, False, False, False, False, False, True, True, False, 
       False, False, False, False, True, True, True, False, True, 
       True, False, False, False, True, True, False], dtype=bool) 

而且我想把它转换成价值的基础上,条件数组:

如果该值是True回报从[-1, 0, 1]随机选择的号码,或返回0

所以在上面的例子中,我要输出的样子:

Out[2]: array([ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
       0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 1, 0, 
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 
       1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0]) 

numpy.where()几乎给了我我想要的东西:

In [3]: numpy.where(multiples, numpy.random.choice([-1, 0, 1], 1), 0) 
Out[3]: array([ 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 0, 
       0, 0, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 
       -1, -1, -1, 0, -1, -1, 0, 0, 0, -1, -1, 0]) 

但问题在于它只执行numpy.random.choice([-1, 0, 1], 1)一次,并保留该结果并在任何地方使用。我希望它每次运行multiples中的值为True

回答

3
out = np.random.randint(-1, 2, multiples.shape) 
out[~multiples] = 0 
+1

或使用'np.where':'np.where(倍数,np.random.randint(-1,2,multiples.shape),0)'。 – Divakar

+0

以同样的方式,我可以使用'np.where(multiples,np.random.choice([ - 1,0,1],multiples.shape,replace = True),0)'。当我为什么没有想到这一点!?!感谢@jmhl和@Divakar。 – Kartik

2

你可以使用np.random.choice列表[-1,0,1]来产生随机数,并把它们在输出数组对应True地方输入数组中,像这样 -

newvals = [-1,0,1] # Values to be put at places of True in input array 

out = np.zeros(multiples.size,dtype=int) # Setup output array 

# Finally use np.random.choice to get random numbers from newvals as many 
# as there are True elements in input array and put into the output array 
# indexed by the corresponding True places in the input array 
out[multiples] = np.random.choice(newvals, multiples.sum(), replace=True) 

采样运行 -

In [44]: multiples 
Out[44]: 
array([ True, True, False, True, True, False, True, True, False, 
     True, False, True, False, True, True, True, True, False, 
     True, True], dtype=bool) 

In [45]: newvals 
Out[45]: [9, 10, 11] 

In [46]: out 
Out[46]: 
array([11, 10, 0, 9, 9, 0, 10, 11, 0, 10, 0, 11, 0, 9, 10, 11, 9, 
     0, 10, 10]) 
+1

为什么要用'非零'? – user2357112

+1

@ user2357112因为我需要使用'idx.​​size'来计算'nonzeros'的数量。我想我可以在那里使用'multiples.sum()'。 – Divakar

+0

你以前用idx和非零的解决方案对我来说更直观。无论如何,很好的答案,我正在努力解决它。 –

0

您是否尝试制作for循环?

for k in range(0,your x size): 
    for j in range(0, your y size): 
     if array[k][j] == True: 
      array[k][j] = (which value you want) 
     else: 
      array[k][j] = (which value you want) 

如果你想录制,定义一个新的MATRIS作为A=np.zeros((xsize,ysize), 'uint8') 然后在第二个加A[k][j] = array[k][j] for循环。

用于显示它print (A)将帮助你..

+0

For循环效率非常低。谢谢你的回答,但它非常简单和低效。请首先阅读关于如何避免Python中的循环的更多信息。 – Kartik

+0

但它的工作。在设计解决方案中有2个法律。 1-保持简单而愚蠢的两种方法不止一种方式。但是,谢谢你的低效评论。 @Kartik –

+0

我不只是想让它工作。即使它在理论上起作用,如果它花费的时间超过一定时间,它仍然被认为是失败的。我有数十亿条记录要处理,并有最后期限要见面。如果一个模型不起作用,我需要尝试其他模型,记录整个过程,以及其他许多事情。始终在项目开始和截止日期之间完成我所需要的所有工作。处理器速度只能节省那么多时间,因此是优化的原因。我向他们报告的人永远不会同意等待循环结束。 – Kartik