5
$\begingroup$

If I have a matrix or table of data,

Data = {{1, 2, 3}, {3, 4, 5}, {5, 6, 7}, {7, 8, 9}, {9, 10, 11}, {11, 12, 
  13}, {13, 14, 15}, {15, 16, 17}, {17, 18, 19}, {19, 20, 21}, {21, 
  22, 23}, {23, 24, 25}, {25, 26, 27}, {27, 28, 29}, {29, 30, 
  31}, {31, 32, 33}}

Is there a method of deleting or dropping a row if any column has the value defined by a list, e.g.

TestList = {1, 8 , 16, 24}

such that if any element contains one of those values then the row itself is removed?

It's achievable by using nested Select statements where you would have a Select for each column and test them individually against the list, using MemberQ but that seems a little crude.

$\endgroup$
8
  • 2
    $\begingroup$ Something like Select[Data, Intersection[TestList, #] === {} &]? $\endgroup$ Nov 19, 2019 at 14:09
  • $\begingroup$ Can this also work for the opposite case? So Select all columns which do not contain any of the test list values? $\endgroup$
    – user27119
    Nov 19, 2019 at 14:12
  • $\begingroup$ You might be interested in using Transpose[] for that. $\endgroup$ Nov 19, 2019 at 14:14
  • $\begingroup$ Thanks, I'll have a play, your first suggestion works great! $\endgroup$
    – user27119
    Nov 19, 2019 at 14:16
  • 2
    $\begingroup$ Also take a look at ContainsNone and similar functions: They are really only syntactic sugar, but they make for very readable code. For instance, your row-wise requirement could be written as Select[Data, ContainsNone[TestList]]. $\endgroup$
    – MarcoB
    Nov 19, 2019 at 14:30

1 Answer 1

7
$\begingroup$

Let's create some play data:

SeedRandom[1234]
data = RandomInteger[{1, 20}, {10, 5}]

testlist = {2, 15, 19};

(*
{{ 2,  2,  1, 17, 18}, 
 { 5,  6, 20, 16, 17},
 {20,  3, 13,  6, 17},
 {19,  8, 15, 17,  7},
 { 2, 16,  8,  9, 14},
 {14,  2, 16,  9,  5},
 { 3, 17,  5, 17,  2},
 {14, 18, 10, 12,  7},
 {15, 19, 12,  3,  5},
 {17, 16, 12, 10, 15}}
*)

Your first task, as stated in the question, can be accomplished with:

Select[data, ContainsNone[testlist]]

(* {{ 5,  6, 20, 16, 17},
    {20,  3, 13,  6, 17},
    {14, 18, 10, 12,  7}} *)

The second task you outlined in comments, wanting to apply the filter only on certain columns (say, for instance, the first, third, and fourth), could be done with:

Select[data, ContainsNone[#[[{1, 3, 4}]], testlist] &]

(* 
{{ 5,  6, 20, 16, 17}, 
 {20,  3, 13,  6, 17},
 {14,  2, 16,  9,  5},
 { 3, 17,  5, 17,  2}, 
 {14, 18, 10, 12,  7},
 {17, 16, 12, 10, 15}} *)
$\endgroup$
1
  • $\begingroup$ Really awesome answer, short and simple! $\endgroup$
    – user27119
    Nov 19, 2019 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.