Подсчитайте, сколько значений попадает в каждую корзину - PullRequest
0 голосов
/ 02 марта 2019

Предположим, у меня есть набор разделов P за интервал [0,1).P имеет длину N.Например:

P = np.array([0,0.05,0.1,0.3,0.7,1])

, который делит [0,1) на следующие интервалы:

[0,0.05), [0.05,0.1), [0.1,0.3), [0.3,0.7) , [0.7,1)

У меня есть другой массив U длины K над [0,1), элементы которогоu+i/K для i = 0,...,K-1, где 0<u<1/K.Например,

U = np.array([0.03,0.13,0.23,0.33,0.43,0.53,0.63,0.73,0.83,0.93])

Я хочу подсчитать количество элементов в U, попадающих в каждый раздел j = 0, ..., N-1.В этом примере у нас есть

C = np.array([1,0,2,4,3])

Есть ли способ сделать это без использования цикла?

1 Ответ

0 голосов
/ 02 марта 2019

Одним из способов является использование np.searchsorted для получения индексов, где элементы в U должны быть вставлены в P для поддержания порядка, после чего следует np.bincount дляполучить счетчик количества вхождений каждого индекса:

np.bincount(np.searchsorted(P,U))[1:]
# array([1, 0, 2, 4, 3])

Или с np.digitize, предполагая, что ячейки всегда увеличиваются монотонно:

np.bincount(np.digitize(U,P))[1:]
# array([1, 0, 2, 4, 3])

Детали

P = np.array([0,0.05,0.1,0.3,0.7,1])
U = np.array([0.03,0.13,0.23,0.33,0.43,0.53,0.63,0.73,0.83,0.93])

Как уже упоминалось, np.searchsorted вернет индексы, при которых элементы в U должны быть вставлены в P, чтобы последние оставались упорядоченными:

s = np.searchsorted(P,U)
# array([1, 3, 3, 4, 4, 4, 4, 5, 5, 5])

Следующее, что мы хотим, это подсчитать количество вхождений каждого индекса.Для этого мы можем использовать np.bincount, который будет делать именно то, что мы хотим.Обратите внимание, что возвращенный массив bining будет иметь до np.amax(x)+1 отсчетов, что означает, что он также будет выводить отсчет 0 для пропущенных значений, в данном случае 2, что соответствует интервалу [0.05,0.1):

np.bincount(s)[1:]
# array([1, 0, 2, 4, 3])
...