Эквивалентная функция для numpy.random.choice в C++

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

Есть ли в C++/opencv функция, которая эквивалентна следующему коду:

np.random.choice(len(vec), samples, p=probabilities[:,0], replace=True)

Заранее спасибо.

3 ответа

Что ж, давайте посмотрим на:

numpy.random.choice(a, size=None, replace=True, p=None)

ссылка на сайт

-> см. мой комментарий, я полагаю, вы перепутали некоторые параметры функции.

Для ввода a Вы используете массив образцов. В качестве выходного размера вы хотите len(vec), вы хотите выборку с заменой и иметь пользовательское неравномерное распределение.

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

C++ предлагает помощь в создании неравномерных распределенных чисел, являясь std::discrete_distribution

Пример:

#include <random>
#include <vector>
#include <algorithm>

using std::vector;

int main()
{
    const int outputSize = 10;

    vector<double> vec(outputSize);

    const vector<double> samples{ 1, 2, 3, 4, 5, 6, 7 };
    const vector<double> probabilities{ 0.1, 0.2, 0.1, 0.5, 0,1 };

    std::default_random_engine generator;
    std::discrete_distribution<int> distribution(probabilities.begin(), probabilities.end());

    vector<int> indices(vec.size());
    std::generate(indices.begin(), indices.end(), [&generator, &distribution]() { return distribution(generator); });

    std::transform(indices.begin(), indices.end(), vec.begin(), [&samples](int index) { return samples[index]; });

    return 0;
}

редактировать: ссылка, кажется, предполагает, что std::default_random_engine выполняет отбор проб с заменой.

Кажется, вы ищете выборку из дискретного случайного распределения

пример на этой странице довольно показателен:

// discrete_distribution
#include <iostream>
#include <random>

int main()
{
  const int nrolls = 10000; // number of experiments
  const int nstars = 100;   // maximum number of stars to distribute

  std::default_random_engine generator;
  std::discrete_distribution<int> distribution {2,2,1,1,2,2,1,1,2,2};

  int p[10]={};

  for (int i=0; i<nrolls; ++i) {
    int number = distribution(generator);
    ++p[number];
  }

  std::cout << "a discrete_distribution:" << std::endl;
  for (int i=0; i<10; ++i)
    std::cout << i << ": " << std::string(p[i]*nstars/nrolls,'*') << std::endl;

  return 0;
}

Я не думаю, что есть функция, которая дает вам это бесплатно. Возможно, вам придется написать это самостоятельно.

Некоторые советы о том, как написать такую ​​функцию:

  • Допустим, у вас есть vector<float> сохраняя ваши вероятности. Первое использование std::partial_sum по этому вектору, чтобы получить накопленные вероятности элементов.
  • Затем для каждой выборки сгенерируйте случайное число с плавающей точкой от 0 до 1. Давайте назовем его random_value, Перебирайте свой вектор накопленных вероятностей, пока не найдете значение больше random_value, Индекс на данный момент является вашим примером индекса. Возьмите значение по этому индексу в вашем samples вектор, сохраните его где-нибудь и повторите.
Другие вопросы по тегам