Выбор случайной выборки из каждой строки массива Numpy, исключая отрицательные числа - PullRequest
3 голосов
/ 30 июня 2010

У меня есть массив 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, не обрабатывая каждую строку отдельно.

1 Ответ

3 голосов
/ 01 июля 2010

Я действительно не думаю, что в Numpy вы найдете что-то, что в точности соответствует тому, что вы просите, поэтому я решил предложить, какие оптимизации я мог бы придумать.

Есть несколько вещей, которые могут сделать это медленно. Во-первых, numpy.where() довольно медленный, потому что он должен проверять каждое значение в массиве срезов (срез также генерируется для каждой строки), а затем генерировать массив значений. Лучшее, что вы можете сделать, если планируете выполнять этот процесс снова и снова на одной и той же матрице, - это сортировать каждую строку. Тогда вы просто используете бинарный поиск, чтобы найти, где начинаются положительные значения, и просто используете случайное число, чтобы выбрать значение из них. Конечно, вы также можете просто хранить индексы, с которых начинаются положительные значения, после нахождения их один раз с помощью бинарных поисков.

Если вы не планируете выполнять этот процесс много раз, то я бы порекомендовал использовать Cython для ускорения строки numpy.where. Cython позволит вам не разбивать строки и ускорить процесс в целом.

Мое последнее предложение - использовать random.choice, а не random.sample, если вы действительно не планируете выбирать размеры выборки больше 1.

...