【问题标题】:How to take n samples from vector? [duplicate]如何从向量中提取 n 个样本? [复制]
【发布时间】:2018-11-07 07:48:39
【问题描述】:

我的问题是如何从vec.begin()vec.end() 中选择n 个元素,这样我们几乎可以覆盖所有的向量元素?

vector<double> take_100_samples(vector<double>& in)
{
  vector<double> vec(100);
  double step = (in.size() - 1) / (100 - 1);

// sampling process

  return vec;
} 

例如,如果in 向量的大小为 200,我们选择它的每两个元素(即 in[0]in[2]in[4]、...、in[199])但如果大小为不能被 100 整除?

有没有有效的方法来做到这一点?
问候

【问题讨论】:

  • 你想要的可能是std::sample
  • 只取一个样本时,“覆盖所有元素”是什么意思?它是关于存储在向量中的值的范围吗?是要确保你至少拿第一个和最后一个吗?如果 in 向量的元素少于 100 个怎么办?
  • @Christophe 即对于尺寸为 200 和步骤 2 的 vec,我们几乎涵盖了所有元素......只是一个很好的步骤定义。并且我们总是确定输入向量的大小大于 100
  • 我认为带有 random_device 的 std::sample 在这里是不够的,因为它不会均匀地填充结果。这意味着 200 个元素不能保证每隔一个元素!
  • 没错,这个问题没有随机性,是均匀采样,不是随机均匀采样。

标签: c++ vector sampling


【解决方案1】:

这样做的通常方法是获取浮点分数,然后将其四舍五入为整数:

double step = in.size() / 100.;

for(int i = 0; i < 100; ++i)
{
    auto index = std::lround(i * step);
    // use index
}

当然,如果您想始终获取第一个和最后一个元素,请调整步计算以及循环。

【讨论】:

  • 需要除以100.0,否则整数除...
  • 是的,当然...我修改了我的帖子并错误地删除了双重演员...
  • 关于术语的一点说明:四舍五入的不是分数step,而是相位=i * step。无论如何,好的和快速的解决方案
  • 强制选择第一个和最后一个元素的简单方法是使用 step = (in.size() -1)/99.0;
  • 是的,这就是OP使用的,这就是我说的他可以根据他要选择的元素使用。
【解决方案2】:

我的解释是你想用异步频率对信号进行下采样。

一种方法是实现一种数字 PLL(锁相环)。

让我们假设您的输入有 N = 1030 个元素,并且您想要获得 K = 100 个元素。
平均速率等于 rate = 10.3。 在实践中,您必须使用等于 10 或 11 的步长,具体取决于索引的当前位置。

如果您处于“提前”状态:step = 10(减速)
如果你“迟到”:step = 11(加速)

测试以了解您是迟到还是提前:
当前的“读取”索引 i 等于前面步骤的总和。 k 是输出索引
如果 i : 你迟到了
否则你提前了

这是基本思想。一些小的调整是可能的,例如确保获得最后一个元素。

编辑:我刚刚“重新发现”了 Mathieu Brucher 的解决方案。在我第一次读得太快时,我被他回答中关于步数计算的原始错误(已更正)误导了。很明显,结果将是等效的,只是 Mathieu Brucher 的实现更简单。在这种情况下,我的答案的唯一兴趣(?)是提供对该过程的另一种解释

【讨论】:

    猜你喜欢
    • 2017-06-22
    • 1970-01-01
    • 2017-08-31
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    相关资源
    最近更新 更多