Use # (Copy) as selection or filter on 2-d array

Viewed 100

The J primitive Copy (#) can be used as a filter function, such as

k =: i.8
(k>3) # k
4 5 6 7

That's essentially

0 0 0 0 1 1 1 1 # i.8

The question is if the right-hand side of # is 2-d or higher rank shaped array, how to make a selection using #, if possible. For example:

k =: 2 4 $ i.8

(k > 3) # k

I got length error

What is the right way to make such a selection?

1 Answers

You can use the appropriate verb rank to get something like a 2d-selection:

(2 | k) #"1 1 k
1 3
5 7

but the requested axes have to be filled with 0s (or !.) to keep the correct shape:

(k > 3) #("1 1) k
0 0 0 0
4 5 6 7

(k > 2) #("1 1) k
3 0 0 0
4 5 6 7

You have to better define select for dimensions > 1 because now you have a structure. How do you discard values? Do you keep empty "cells"? Do you replace with 0s? Is structure important for the result?

If, for example, you only need the "values where" then just ravel , the array:

(,k > 2) # ,k
3 4 5 6 7

If you need to "replace where", then you can use amend }:

u =: 5 :'I. , 5 >  y'     NB. indices where 5 > y
0 u } k
0 0 0 0
0 5 6 7

z =: 3 2 4 $ i.25
u =: 4 :'I. , (5 > y) +. (0 = 3|y)'     NB. indices where 5>y or 3 divides y
_999 u } z
_999 _999 _999 _999
_999    5 _999    7

  8 _999   10   11
_999   13   14 _999

 16   17 _999   19
 20 _999   22   23
Related