Учитывая массив пороговых значений numpy
, каков наиболее эффективный способ создания массива счетчиков другого массива, удовлетворяющего этим значениям?Быстрый подсчет элементов массива numpy по значениям порогов в другом массиве
Предположим, что массив порогового значения мал и отсортирован, а массив значений, подлежащих подсчету, является большим и является несортированным.
Пример: для каждого элемента valueLevels
, подсчитывать элементы values
больше или равна ей:
import numpy as np
n = int(1e5) # size of example
# example levels: the sequence 0, 1., 2.5, 5., 7.5, 10, 5, ... 50000, 75000
valueLevels = np.concatenate(
[np.array([0.]),
np.concatenate([ [ x*10**y for x in [1., 2.5, 5., 7.5] ]
for y in range(5) ])
]
)
np.random.seed(123)
values = np.random.uniform(low=0, high=1e5, size=n)
До сих пор я пытался список понимание подхода.
np.array([sum(values>=x) for x in valueLevels])
было неприемлемо медленноnp.array([len(values[values>=x]) for x in valueLevels])
было улучшение- сортировки
values
сделал ускорить понимание (в этом примере, от ~ 7 до 0,5 мс), но стоимость рода (~ 8 мс) превысил сбережения для одноразового использования
лучшее, что я сейчас это понимание this approach:
%%timeit
np.array([np.count_nonzero(values>=x) for x in valueLevels])
# 1000 loops, best of 3: 1.26 ms per loop
, который является приемлемым для моих целей, но из любопытства,
То, что я хотел бы знать, является
- Если список понимание является путь, это может быть ускорено? Или,
- Существуют ли другие подходы быстрее? (У меня есть смутное ощущение, что это можно сделать, передавая массив значений по массиву пороговых значений, но я не могу понять, как получить размеры для
np.broadcast_arrays()
.
Хорошо знать, как сделать 2D-подход, +1. С точки зрения производительности, я тоже не вижу решающей разницы. Я приму это, если ничего не выйдет. Благодарю. – C8H10N4O2
Yup, я добавил новую ось вдоль более длинного массива по ошибке, заплатив штраф. Хорошая работа с 'count_nonzero'! – Divakar