Выборка данных в две группы

Я ищу помощь, чтобы сделать приведенный ниже код эффективным. Я не удовлетворен, хотя это работает. Ошибка должна быть исправлена ​​(в настоящее время не имеет значения). Я использую заголовок в первый раз и stable_partition в первый раз.

Определение проблемы / спецификация:
У меня есть совокупность (вектор) числовых данных (значения с плавающей запятой). Я хочу создать два СЛУЧАЙНЫХ образца (2 вектора) на основе указанного пользователем процента. то есть popu_data = 30%Sample1 + 70%Sample2 - здесь 30% будет предоставлено пользователем. Я еще не реализовал как%, но это тривиально.

Проблема в программировании: я могу создать 30% выборку от населения. Вторая часть создания другого вектора (sample2 - 70%) - моя проблема. Причина в том, что при выборе данных 30%, я должен выбрать значения случайным образом. Я должен следить за индексами, чтобы удалить их. Но кое-что, как я не получаю эффективную логику, чем та, которую я реализовал.

Моя логика (НЕ радует): в данных о населении значения в случайных индексах заменяются уникальным значением (здесь оно составляет 0,5555). Позже я узнал о функции stable_partition, где отдельные значения Population сравниваются с 0,5555. При значении false эти данные создаются как новый Sample2, который дополняет sample1.

В дополнение к этому: Как я могу сделать этот Generic, то есть популяцию, в 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;
}

1 ответ

Решение

Учитывая требование к 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()); 

Для некоторых типов элементов в массиве вы можете улучшить это, переместив элементы из исходного массива в массив образцов, но для простых типов, таких как float или же doubleЭто ничего не даст.

Другие вопросы по тегам