2010-06-30 69 views
2

我有一个numpy的阵列,其看起来像选择从numpy的阵列的每一行的随机样品,不含负数

>>> a 
array([[ 3. , 2. , -1. ], 
     [-1. , 0.1, 3. ], 
     [-1. , 2. , 3.5]]) 

我想选择从随机的每一行的值,但我想排除随机抽样中的-1值。

我目前做的是:

x=[] 
for i in range(a.shape[0]): 
    idx=numpy.where(a[i,:]>0)[0] 
    idxr=random.sample(idx,1)[0] 
    xi=a[i,idxr] 
    x.append(xi) 

,并得到

>>> x 
[3.0, 3.0, 2.0] 

这成为大型阵列的速度有点慢,我想知道是否有一种方法可以有条件地选择随机来自原始a矩阵的值不分别处理每行。

+0

我没有与任何NumPy的经验,但我也能猜到样本量生成一个随机数比从数组中访问数据花费的时间要长。追加到列表中也是如此。你有没有分析你的程序,以确保你正在优化正确的事情? – torak 2010-06-30 16:24:04

+0

我已经对程序进行了剖析,'idx'和'idxr'这两行是最慢的,每次花费的时间几乎相等。 – fideli 2010-06-30 17:11:56

+0

您是否总是希望在每一行中具有相同数量的排除值?如果是这样,你可以矢量化整个事情,并在没有python循环的两行代码中执行它... – 2010-06-30 22:18:56

回答

3

我真的不认为你会在Numpy中发现任何你正在打包的东西,所以我决定提供我可以想到的优化。

有几件事可能会让这里变得很慢。首先,numpy.where()相当慢,因为它必须检查切片数组中的每个值(切片也是为每行生成的),然后生成一组值。如果你计划在同一个矩阵上重复执行这个过程,你可以做的最好的事情就是对每一行进行排序。然后,您只需使用二进制搜索来查找正值开始的位置,并使用随机数字从中选择一个值。当然,您也可以在用二进制搜索查找一次后,将正值的索引存储起来。

如果您不打算多次完成此过程,那么我会建议使用Cython来加速numpy.where行。 Cython将允许您不需要将行分割出来并加速整个过程。

我最后的建议是使用random.choice而非random.sample除非你真的做计划的选择是大于1

+0

我将在类似的,但新生成的阵列上做这个过程很多次,所以我会研究Cython。谢谢! – fideli 2010-07-01 13:42:44