11

I have a matrix a n columns and m lines. I'd like to efficiently remove the lines that are not entirely composed of numeric values, lines like this:

{6.22926,6.23254,6.23128,,6.23453,6.22548,6.22938,6.23443,}

In this case the last element is not a numeric value, and such line should be removed.

Also, the matrix is quite big, I have no clue what an efficient method would be.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Cedric H.
  • 696
  • 1
  • 4
  • 15

3 Answers3

16

The following should work:

lis = {{1, 2, 3, 4, 5, 6}, {1, 9, , 4, 6, 2}, {4, a, 3, 7, 1, 2}, 
      {3.4, 5.2, 6.5, 7.7, 6.1, 2}};

Then:

Cases[lis, {__?NumericQ}]
{{1, 2, 3, 4, 5, 6}, {3.4, 5.2, 6.5, 7.7, 6.1, 2}}

We can also use VectorQ with Select

Select[lis, VectorQ[#, NumericQ] &]

If you have Version 10, the following works:

Select[lis, AllTrue @ NumericQ]
RunnyKine
  • 33,088
  • 3
  • 109
  • 176
9
m = {{6.22926, 6.23254, 6.23128, 0, 6.23453, 6.22548, 6.22938, 
   6.23443, 0}, {6.22926, 6.23254, 6.23128, , 6.23453, 6.22548, 
   6.22938, 6.23443,}}

Select[m, MatrixQ[{#}, NumericQ] &]
{{6.22926, 6.23254, 6.23128, 0, 6.23453, 6.22548, 6.22938, 6.23443, 0}}

more alternatives for speed comparisons.

Öskå
  • 8,587
  • 4
  • 30
  • 49
Wouter
  • 1,343
  • 7
  • 11
6
m = {{1, 2, 3}, {, 2, 3}, {1.1, 2, 3}, {1.1, , 3}}

DeleteCases[m, 
 Alternatives @@ Select[m, MemberQ[#, _?(Not[NumericQ[#]] &)] &]]

{{1, 2, 3}, {1.1, 2, 3}}

Edit

A timing comparison. First creating a matrix:-

m = RandomReal[1, {10000, 10000}];

(* Adding some blanks *)
(m[[Sequence @@ #]] = "") & /@ RandomInteger[{1, 10000}, {2000, 2}];

Comparing the various solutions:-

First@Timing[a = Cases[m, {__?NumericQ}]]

19.141323

First@Timing[b = Select[m, MatrixQ[{#}, NumericQ] &]]

0.468003

First@Timing[
  c = DeleteCases[m, 
    Alternatives @@ Select[m, MemberQ[#, _?(Not[NumericQ[#]] &)] &]]]

85.862950

a == b == c

True

Chris Degnen
  • 30,927
  • 2
  • 54
  • 108