当多个选择时,在numpy数组中查找随机出现

时间:2018-04-26 20:49:30

标签: python numpy

我编写了这段代码来实现从匹配谓词条件的元素列表中返回随机值的目标:

N=<int>
sampl = np.random.randint(low=0, high=N+1, size=(10,))
xs = np.where(sampl == 1)
ys = np.array([tuple(x) for x in xs], dtype=int)[0]
x = np.random.choice(ys)

例如:如果我使用N=2运行代码,而我只在数组中查找1

    sampl = np.random.randint(low=0, high=N+1, size=(10,))

--> sampl = [2 1 0 0 0 1 0 0 2 1]

    xs = np.where(sampl == 1)

--> [2 1 0 0 0 1 0 0 2 1]  # Positions 1, 5, 9 are of interest. 
       ^       ^       ^ 

    ys = np.array([tuple(x) for x in xs], dtype=int)[0]

--> ys = [1 5 9] # Put them in an array. 

    x = np.random.choice(ys)

--> x = 9 # Pick a random one and return it

它有效,但它并不简洁,我遇到了一些问题,试图让它更优雅。

    除了条件之外,
  • numpy.where()只传递一个元组。我尝试传递x=sampl,但运行时抱怨说该函数没有使用参数(当我检查代码时它会这样做。)
  • 再一次,从元组中创建一个numpy数组迫使我返回第一个元素。在测试边缘情况时(例如谓词没有找到值),这容易出错。

您对改进此代码有什么建议吗?我想坚持numpy / pandas,因为阵列会变得非常大。

1 个答案:

答案 0 :(得分:1)

我能想到的最优雅的方式可能是随机洗牌你的阵列,然后拉下第一次出现。这应该非常简洁。

类似于:

np.random.shuffle(sampl)
x = np.ravel(np.where(sampl==1))[0]

或者,就像你的建议,没有改组,看起来像

x = np.random.choice(np.ravel(np.where(sampl==1)))

第二个想法,我猜choice方法比无聊更快。

下一个问题是边缘情况。如何处理这取决于您对默认行为的期望。如果您希望在大多数情况下条件至少会出现一次,那么您应该在没有异常命中的情况下处理:

try: 
   x = np.random.choice(np.ravel(np.where(sampl==1)))
except: 
   # TODO
   pass

我强烈建议这样做,除非你很少发现。但是不要接受我的话......时间就是你自己。

另一种选择是放入明确检查

的条件
np.size( np.where(sampl==1) ) > 0

继续之前。但是,我猜这种方法比try...except方法慢。