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));
Your Answer
1 Answer
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));