与C ++中的numpy.random.choice等效的函数

时间:2017-03-21 11:45:51

标签: c++ opencv c++11 non-uniform-distribution

我需要你的帮助来解决以下问题:

c ++ / opencv中是否有一个函数,它等同于以下代码:

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

提前致谢。

3 个答案:

答案 0 :(得分:5)

好吧,让我们来看看:

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

link

- >看到我的评论,我想你混淆了一些函数的参数。

对于输入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;
}

修改:link似乎建议std::default_random_engine使用替换执行采样。

答案 1 :(得分:2)

我认为没有一个功能可以免费提供给你。你可能要自己写。

关于如何编写这样一个函数的一些提示:

  • 我们假设您有vector<float>存储您的概率。首先在此向量上使用std::partial_sum来获取元素的累积概率。
  • 然后,对于每个样本,生成0到1之间的随机浮点数。我们称之为random_value。迭代累积概率的向量,直到找到大于random_value的值。此时的索引是您的样本索引。获取samples向量中此索引处的值,将其存储在某处并重复。

答案 2 :(得分:2)

您似乎希望从discrete random distribution

进行抽样

该页面上的示例很有说服力:

// 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;
}