2016-09-14 2 views
0

У меня есть вектор g значений длины 1024 и меньшего вектора f размера 32, определяющего границы бинов. v и f сортируются по возрастанию. Я хочу вернуть массив векторов i.e [v_1,v_2,v_3,...] длиной len(f), так что каждый вектор v_i содержит индексы g между f_i и f_i + 1. Есть ли способ NumPy делать такую ​​вещь, которая не включает цикл?numpy binning: как получить индексы массива, удовлетворяющие предикату

ответ

1

Вы можете использовать searchsorted найти отсортированный позиции f в g. Они дают нижние и верхние границы диапазонов, которые вы хотите:

Например,

In [42]: g 
Out[42]: 
array([ 1, 11, 19, 20, 21, 32, 36, 41, 47, 53, 54, 55, 65, 66, 69, 74, 76, 
     87, 89, 94]) 

In [43]: f 
Out[43]: [0, 10, 20, 50, 100] 

In [44]: binedges = g.searchsorted(f) 

In [45]: binedges 
Out[45]: array([ 0, 1, 3, 9, 20]) 

Массив binedges дает вам всю информацию, что вам нужно: диапазон индексов для бен k является range(binedges[k], binedges[k+1]).

Вот как вы можете создать явный список индексов в каждом бине:

In [46]: rngs = [list(range(binedges[k], binedges[k+1])) for k in range(len(binedges)-1)] 

In [47]: rngs 
Out[47]: [[0], [1, 2], [3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]] 
+0

Спасибо. Это хорошо работает. – LostInTheFrequencyDomain

0

Первые вещи сначала:

import numpy as np 

скажем, у вас есть ваши данные g:

g = sorted((1e3 * np.random.random(1024)).astype(int)) 

и ваши контейнеры f:

f = sorted((1e3 * np.random.random(32)).astype(int)) 

вы можете использовать numpy.digitize, которые возвращают индексы bin в f, где eac ч элемент g принадлежит:

dg = np.digitize(g,f) 

Результирующий вектор собирается содержит список различных размеров, так что вы можете хранить это список:

for i in range(len(f)): v.append(np.argwhere(dg == i)) 
Смежные вопросы