Python 从Numpy数组的每行中选择一个随机样本,不包括负数

Python 从Numpy数组的每行中选择一个随机样本,不包括负数,python,random,numpy,Python,Random,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

我有一个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
矩阵中选择随机值,而无需单独处理每一行。

我真的不认为你会在Numpy中找到任何能完全满足你打包要求的东西,所以我决定提供我能想到的优化

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

如果您不打算多次执行此过程,那么我建议使用Cython来加速numpy.where行。Cython将允许您不需要将行切掉,从而加快整个过程


我的最后一个建议是使用random.choice而不是random.sample,除非您确实计划选择大于1的样本大小。

我没有任何NumPy经验,但我猜生成随机数所需的时间比从数组中访问值所需的时间要长。添加到列表中也是如此。您是否分析了您的程序以确保优化了正确的内容?我已经分析了该程序,
idx
idxr
行是最慢的,在每行上花费的时间几乎相等。您是否总是希望每行中都有相同数量的排除值?如果是这样的话,你可以将整个过程矢量化,并在两行代码中完成,而不需要python循环…@Joe Kington:不一定。出于所有目的,这些行属于独立样本。我将多次在类似但新生成的数组上执行此过程,因此我将研究Cython。谢谢