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$ – J. M.'s ennui Nov 19 '19 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$ – Q.P. Nov 19 '19 at 14:12
  • $\begingroup$ You might be interested in using Transpose[] for that. $\endgroup$ – J. M.'s ennui Nov 19 '19 at 14:14
  • $\begingroup$ Thanks, I'll have a play, your first suggestion works great! $\endgroup$ – Q.P. Nov 19 '19 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 '19 at 14:30
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$ – Q.P. Nov 19 '19 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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