将数据采样为两组

Sampling Data into two Groups

本文关键字:两组 数据 采样      更新时间:2023-10-16

我正在寻求帮助,以使下面的代码高效。虽然它有效,但我并不满意。有一个错误需要修复(目前不相关)。我正在使用<random>header和stable_partition。

问题定义/规范:
我有一个数字数据(浮点值)的总体(向量)。我想根据用户指定的百分比创建两个随机样本(2个向量)。即popu_data=30%Sample1+70%Sample2-这里30%将由用户给出。我还没有实现%,但它微不足道。

编程中的问题:我能够从总体中创建30%的样本。创建另一个向量(样本2-70%)的第二部分是我的问题。原因是在选择30%的数据时,我必须随机选择值。我必须跟踪索引才能删除它们。但有些人说,我没有得到一个比我实现的逻辑更有效的逻辑。

我的逻辑是(不高兴):在总体数据中,随机索引的值被替换为一个唯一的值(这里是0.5555)。后来我了解了stable_partition函数,其中将总体的单个值与0.5555进行比较。在false时,该数据被创建为新的Sample2,它补充了sample1。

除此之外:我如何使此通用,即将总体划分为用户定义的总体%的N个子样本。

谢谢你的帮助。我尝试过矢量擦除、移除、复制等,但它没有实现为当前代码。我正在寻找一个更好、更高效的逻辑和stl使用。

#include <random>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool Is05555 (float i){
    if ( i > 0.5560 ) return true;
    return false;
}
int main()
{
    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<> dis(1, 2);
    vector<float>randVals;
    cout<<"All the Random Values between 1 and 2"<<endl;
    for (int n = 0; n < 20; ++n) {
        float rnv = dis(gen);
        cout<<rnv<<endl;
        randVals.push_back(rnv);
    }
    cout << 'n';
    random_device rd2;
    mt19937 gen2(rd2());
    uniform_int_distribution<int> dist(0,19);
    vector<float>sample;
    vector<float>sample2;
    for (int n = 0; n < 6; ++n) {
        float rnv = dist(gen2);
        sample.push_back(randVals.at(rnv));
        randVals.at(rnv) = 0.5555;
    }
    cout<<"Random Values between 1 and 2 with 0.5555 a Unique VAlue"<<endl;
    for (int n = 0; n < 20; ++n) {
        cout<<randVals.at(n)<<" ";
    }
    cout << 'n';
    std::vector<float>::iterator bound;
    bound = std::stable_partition (randVals.begin(), randVals.end(), Is05555);
    for (std::vector<float>::iterator it=randVals.begin(); it!=bound; ++it)
        sample2.push_back(*it);
    cout<<sample.size()<<","<<sample2.size()<<endl;
    cout<<"Random Values between 1 and 2 Subset of 6 only: "<<endl;
    for (int n = 0; n < sample.size(); ++n) {
        cout<<sample.at(n)<<" ";
    }
    cout << 'n';
    cout<<"Random Values between 1 and 2 - Remaining: "<<endl;
    for (int n = 0; n < sample2.size(); ++n) {
        cout<<sample2.at(n)<<" ";
    }
    cout << 'n';
    return 0;
}

给定一个N%样本的要求,与订单无关,可能最简单的做法是:

std::random_shuffle(randVals.begin(), randVals.end());
int num = randVals.size() * percent / 100.0;
auto pos = randVals.begin() + randVals.size() - num;
// get our sample
auto sample1{pos, randVals.end()};
// remove sample from original collection
randVals.erase(pos, randVals.end()); 

对于数组中的某些类型的项,可以通过将项从原始数组移动到示例数组来改进这一点,但对于像floatdouble这样的简单类型,这将无法完成任何任务。