mask and apply numpy where function to a vector in c++

Question:

I’m using C++ and want to combine the masking of a vector and the search for the indexes where a condition is verified, similarly to the numpy where function.

Here’s an example:

std::vector<int> id     = {61, 66, 68, 80}
std::vector<int> val    = {0, 0, 2, 1};
std::vector<int> offset = {62, 65, 70};
std::vector<int> masked;

After using

masked = offset[val];

masked should look like this: masked = {62, 62, 70, 65}

Afterwards, I want to find the indexes where id vector elements are greater than masked ones. Both vectors have the same length. This is equivalent to Numpy’s where function in Python.

c = np.where(id > masked)[0]

c is an equivalent of vector<int> and should look like this: c = {1,3}

Any ideas out there? Thank you!

Asked By: fslack

||

Answers:

You can just use a simple loop. Note that you do not need the intermediate array masked. Here is an (untested) example:

std::vector<int> c;
c.reserve(val.size());

for(size_t i=0 ; i<val.size() ; ++i)
    if(id[i] > Offset[val[i]])
        c.push_back(i);
Answered By: Jérôme Richard

For Numpy-like manipulation of arrays, you can use std::valarray:

std::valarray<std::size_t> val = {0, 0, 2, 1};
std::valarray<int> id     = {61, 66, 68, 80}
std::valarray<int> offset = {62, 65, 70};
std::valarray<int> masked = offset[val];

Note that the value_type of val must be std::size_t, as std::valarray<int> is not implicitly convertible to std::valarray<std::size_t> (differently from what happens with int and std::size_t).

For the second part, if you can use C++11, then you may use std::iota (defined in <numeric>) which creates an incrementing sequence:

std::valarray<int> where(id.size());
std::iota(begin(where), end(where), 0);

Then you can do:

std::valarray<int> c = where[id > masked];

You may prefer this writing for readability, although it might be less performant. Here you should find the code example.

Answered By: Ale
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.