Changing values based on filter

Hi there,

Is there an easy way to "filter" values in a matrix and change them without having to do a for-loop?

For example, in Python (with numpy), I can do the following:

my_vec = np.array([100,200,300,400,500,600,700])
my_vec[my_vec >= 400] = -999
print(my_vec)

Notice how it just takes one line of code to do the filtering and the re-assigning.

In that case, I will get the following result:

> [ 100 200 300 -999 -999 -999 -999]

 

The only way I can think about how to do this in GAUSS is as follows:

my_vec = { 100 200 300 400 500 600 700 };
my_vec = my_vec';
filter_cats = 399 | 100000000 ;

idx_cols = indexcat(my_vec, filter_cats);

for i(1,rows(idx_cols),1);
    my_vec[idx_cols[i]] = -999;
endfor;

Note how the procedure above involves a lot more lines of code, the use of the indexcat function along with a for-loop, and a cutoff point which isn't exactly the cutoff point I originally wanted. All of this ends up just looking really sloppy.

Am I missing something? Is there an easier way to do this?

Thanks!!!

1 Answer



0



accepted

I think this is probably the most readable way to do it.

my_vec = { 100 200 300 400 500 600 700 };

// Replace every value in 'my_vec' which is greater
// than or equal to 400 with -999.
my_vec = substute(my_vec', my_vec' .>= 400, -999)';

However, you could also convert the values greater than 400 to a missing value with missex. Then you could convert the missing values to -999 with missrv, like this:

my_vec = { 100 200 300 400 500 600 700 };

// Convert values greater than or equal to 400 into missing
// values and then convert the missing values into -999
my_vec = missrv(missex(my_vec, my_vec .>= 400), -999);

Both of these will turn my_vec into:

my_vec = { 100 200 300 -999 -999 -999 -999 };

I am assuming you will prefer one of the above options, but I just want to point out a couple of changes you could make to your original code:

my_vec = { 100 200 300 400 500 600 700 };

// 399 to +Inf 
filter_cats = 399 | __INFP;

idx_cols = indexcat(my_vec', filter_cats);

// Assign without 'for' loop by reshaping -999 into
// the size to be assigned.
my_vec[idx_cols] = reshape(-999, 1, rows(idx_cols));

aptech

1,773

Your Answer

1 Answer

0
accepted

I think this is probably the most readable way to do it.

my_vec = { 100 200 300 400 500 600 700 };

// Replace every value in 'my_vec' which is greater
// than or equal to 400 with -999.
my_vec = substute(my_vec', my_vec' .>= 400, -999)';

However, you could also convert the values greater than 400 to a missing value with missex. Then you could convert the missing values to -999 with missrv, like this:

my_vec = { 100 200 300 400 500 600 700 };

// Convert values greater than or equal to 400 into missing
// values and then convert the missing values into -999
my_vec = missrv(missex(my_vec, my_vec .>= 400), -999);

Both of these will turn my_vec into:

my_vec = { 100 200 300 -999 -999 -999 -999 };

I am assuming you will prefer one of the above options, but I just want to point out a couple of changes you could make to your original code:

my_vec = { 100 200 300 400 500 600 700 };

// 399 to +Inf 
filter_cats = 399 | __INFP;

idx_cols = indexcat(my_vec', filter_cats);

// Assign without 'for' loop by reshaping -999 into
// the size to be assigned.
my_vec[idx_cols] = reshape(-999, 1, rows(idx_cols));


You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.