Python bisect.bisect () аналог в R?

1

Я хочу рисовать из дискретного распределения.

У меня есть матрица pi, которая состоит из векторов вероятностей (с тем же числом столбцов и суммой каждой строки равно 1).

В Python я могу сделать следующее

cumsumpi = cumsum(pi, axis = 1)
[bisect.bisect(k, random.rand()) for k in cumsumpi]

чтобы получить вектор дроби по вероятности, заданной pi.

Теперь я хочу воспроизвести это с помощью R. Я знаю, что в R есть функция "sample", но кажется, что он использует какой-то другой алгоритм, а затем делит пополам, поэтому я получаю разные рисунки, хотя я использую тот же set.seed() в обоих случаях.

Я использовал rpy2, чтобы получить точно такие же случайные дроби в Python, что и в R. Например,

вместо random.rand(), я использовал   [bisect.bisect(k, asarray (robjects.r('runif (1)'))) для k в cumsumpi]

Пожалуйста, дайте мне знать, есть ли другая функция, чем образец в R, которые делают то же самое.

-Joon

отредактирован: Мне удалось воспроизвести точно такие же розыгрыши со следующим, но это было медленно.

    cumsumpi = t(apply(pi, 1, cumsum))

    getfirstindx = function(cumprobs) {
        return(which(cumprobs > runif(1))[1])
    }

    apply(cumsumpi, 1, getfirstindx)
Теги:

4 ответа

1
Лучший ответ

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

cumsumpi = t(apply(pi, 1, cumsum));
u = runif(nrow(cumsumpi));

max.col((cumsumpi > u) * 1, "first")

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

0

Я не опубликовал его, но то, что я закончил, было довольно похоже:

cumsumpi = t(apply(pi, 1, cumsum))

1 + rowSums(cumsumpi > runif(nrow(pi)))

Скорость была почти такой же, как ваш код. Если бы я знал о max.col, я бы использовал это.

И после вашего предложения, я векторизовал вещь cumsum, и это дало мне нетривиальное увеличение скорости. Спасибо.

-Joon

0

То, что я искал, было findInterval - найти интервальные номера или индексы.:)

0

Я не могу согласовать заголовок вопроса с телом вопроса - в любом случае здесь функция R идентична функции bisect python:

Пакет gtool * s имеет двоичную функцию поиска ** binsearch *, которая почти идентична bisect python, например,

# search for 25 in the range 0 through 100
> binseaerch(fun = function(x) x - 25, range=c(0, 100))

$call
binsearch(fun = function(x) x - 25, range = c(0, 100))

$numiter
[1] 2

$flag
[1] "Found"

$where
[1] 25

$value
[1] 0
  • 0
    Я могу ошибаться, но я не думаю, что это то, что я ищу. Я хочу получить индекс вектора (который состоит из кумулятивных вероятностей - например, [0,1, 0,3, 0,7, 1]), где лежит runif (1). Так, например, если runif (1) draw равняется 0.5, то пополам дает 3, что составляет индекс 0.7. (0,3 <runif (1) = 0,5 <0,7)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню