C ++ Манипуляции с массивами (Python-подобные операции) - PullRequest
2 голосов
/ 24 марта 2010

Я пытаюсь найти лучшую библиотеку / пакет C ++ для манипулирования массивами в стиле python. В принципе, мне нужна такая простота:

values  = numpy.array(inp.data)
idx1    = numpy.where(values > -2.14)
idx2    = numpy.where(values < 2.0)

res1 = (values[idx1] - diff1)/1000
res2 = (values[idx2] - diff2)*1000

В питоне это всего 5 строк, но самый простой способ в C ++, о котором я могу подумать, это довольно много вложенных циклов. Просьба посоветовать ..

В основном мой вопрос касается операций с массивом / вектором, таких как умножение массива, операции с индексами и т. Д. В приведенном выше примере res1 - это массив, содержащий набор элементов, отфильтрованных из массива значений, и некоторую арифметику, примененную впоследствии вычитание, умножение для всех выбранных элементов). В этом примере с Python я не копирую элементы массива значений, так как он может быть достаточно большим с точки зрения памяти, я сохраняю только индексы и хочу иметь возможность выполнять арифметические операции с выбранным набором элементов исходного массива .

Ответы [ 5 ]

5 голосов
/ 24 марта 2010

Вы можете достичь чего-то похожего в C ++, но вам не следует использовать для этого простые массивы C.

Самый простой способ увидеть эту работу - использовать std::set с плавающей точкой (ваш код выглядит так, как будто предполагается, что данные отсортированы в порядке возрастания). Вы также можете использовать std::vector с плавающей точкой, но вам придется отсортировать их самостоятельно, вероятно, используя std::sort.

В этом случае ваш пример кода может выглядеть следующим образом - набор предполагает, что значения уникальны, в противном случае вы можете использовать std::multiset вместо;

std::set<float> values(inp.data.begin(), inp.data.end());
std::set<float>::iterator idx1 = values.lower_bound(-2.14);
std::set<float>::iterator idx2 = values.upper_bound(2.0);

float res1 = (*idx1 - diff1) / 1000.0;
float res2 = (*idx2 - diff2) / 1000.0;

Обратите внимание, что приведенный выше пример кода не является 100% преобразованием вашего исходного кода - lower_bound дает вам первый элемент, который равен или больше -2.14. Я также не вставил никакой проверочный код для сбоев - если lower_bound или upper_bound не может найти подходящие элементы, они вернут, например, values.end().

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

std::vector<float> values(inp.data.begin(), inp.data.end());
std::sort(values.begin(), values.end();
std::vector<float>::iterator idx1 = std::lower_bound(values.begin(), values.end(), -2.14);
std::vector<float>::iterator idx2 = std::upper_bound(values.begin(), values.end(), 2.0);

float res1 = (*idx1 - diff1) / 1000.0;
float res2 = (*idx2 - diff2) / 1000.0;
5 голосов
/ 24 марта 2010

Вы не должны использовать массивы вообще. Пожалуйста, сядьте и узнайте о классе std :: vector, а также об итераторах и алгоритмах стандартной библиотеки. Я настоятельно рекомендую прочитать книгу Стандартная библиотека C ++ .

4 голосов
/ 24 марта 2010

Предлагаю проверить заголовок алгоритма. Также не работайте с массивами, у вас есть std :: vector или boost (скоро будет std) :: array.

статья в Википедии

Справочник по всем алгоритмам

1 голос
/ 24 марта 2010

Если вы объедините std::vector и boost::lambda, вы действительно сможете приблизиться к своему примеру:

#include <algorithm>
#include <iostream>
#include <vector>
#include <boost/lambda/lambda.hpp>

using boost::lambda::_1;

int main() {
    float ary[10] = { -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 };
    std::vector<float> v(&ary[0], &ary[10]);
    std::vector<float>::iterator iter1, iter2;

    iter1 = std::find_if(v.begin(), v.end(), (_1 > -2.14));
    iter2 = std::find_if(v.begin(), v.end(), (_1 < 2.0));

    // output:
    //     iter1 = -2.000
    //     iter2 = 1.000
    std::cout
        << "iter1 = " << *iter1 << "\n"
        << "iter2 = " << *iter2 << "\n"
        << std::endl;
    return 0;
}
1 голос
/ 24 марта 2010

Если я не ошибаюсь, numpy написан в основном на C (с оберткой Python), так что вы можете использовать его напрямую из C ++ без особых усилий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...