从一组数字中抽取一个随机数,不包括某些集合中给出的数字

时间:2016-09-11 17:07:09

标签: python numpy

假设我有两个数组:

{0...9}

我想生成另一个长度为10的数组,其第i个条目是从集合中抽取的随机整数(a[i] 减去元素b[i]和{{1 }})。

作为NumPy的相对新手,我认为最简单的方法可能是:

  1. 获取每个x = {0...9} - (a[i] union b[i])
  2. 的设置差异i
  3. 为每个np.random.choice(x[i], 1)
  4. 执行i

    但我发现这有点棘手,因为我无法弄清楚如何在2个数组之间映射setdiff1d元素。有没有一种明显的方法可以在NumPy中执行此操作(即理想情况下无需使用Python集等)?

2 个答案:

答案 0 :(得分:2)

这是一种方式:

In [87]: col = np.array((a, b)).T # Or as a better way np.column_stack((a,b)); suggested by @Divakar

In [88]: r = np.arange(10)

In [89]: np.ravel([np.random.choice(np.setdiff1d(r, i), 1) for i in col])
Out[89]: array([7, 8, 8, 6, 6, 8, 6, 5, 5, 6])

或者作为一种numpytonic方法:

In [101]: def func(x):                           
             return np.random.choice(np.setdiff1d(r, x), 1)
   .....: 

In [102]: np.apply_along_axis(func, 1, col).ravel()
Out[102]: array([6, 7, 9, 6, 4, 6, 7, 4, 0, 7])

答案 1 :(得分:0)

np.random.choice函数似乎不允许同时对多个集合进行操作。因此,您需要某种形式的循环来为输出的每个元素单独调用np.random.choice。鉴于需要一个循环,我认为没有人能比你在问题中的建议做得更好。以下代码实现了您的想法,并使用列表解析隐藏了所需的循环:

import numpy as np
a = np.random.randint(0,10,10)
b = np.random.randint(0,10,10)
domain = set(range(10))
res = [ np.random.choice(list(domain - set(avoid))) for avoid in zip(a, b) ]
res = np.array(res)