6

Delete is not suitable to delete the rows of a matrix, as illustrated below:

  SeedRandom[0];
; r = 100
; rows = RandomReal[{0, 1}, {r, 2}]
; toDrop = Select[Range[r], PrimeQ]
; reducedRows = Delete[rows, toDrop]

Mathematica graphics

I know that I can always do something like

  toKeep = Complement[Range[r], toDrop]
; reducedRows = rows[[toKeep]]

...but this strikes me as inefficient, at least whenever toKeep is large (IOW, whenever r is much greater than Length[toDrop]).

Is there any other built-in that achieves what Delete[rows, toDrop] aspires to?

kjo
  • 11,717
  • 1
  • 30
  • 89

3 Answers3

10

Probably the simplest way will be:

reducedRows = ReplacePart[rows, Transpose[{toDrop}] -> Nothing[]]
faysou
  • 10,999
  • 3
  • 50
  • 125
ciao
  • 25,774
  • 2
  • 58
  • 139
8

Make the to-be-dropped rows vanish:

rows[[toDrop]] = ##&[]

or as a function:

f = Module[{m = #, d = #2}, m[[d]] = ##&[]; m] &;

f[rows, toDrop]

Some timings

ClearAll[f0, f1, f2, f3, f4, f5]
f0 = ReplacePart[#, Transpose[{#2}] -> Nothing[]]&; (* ciao's answer *)
f1 = ReplacePart[#, Thread[#2 -> Sequence[]]] &; (* v9 version of ciao's answer*)
f2 = Module[{m = #, d = #2}, m[[d]] = ## &[]; m] &;
f3 = #[[Complement[Range@Length@#, #2]]] &; (* from george2079's deleted answer*)
f4 = Delete[#, Transpose[{#2}]] &; (* from ciao's comment *)
f5 = Delete[#, List /@ #2] &; (* from J.M.'s comment *)


SeedRandom[0];
r = 1000000;
rows = RandomReal[{0, 1}, {r, 2}];
toDrop = Select[Range[r], PrimeQ];
{HoldForm[#], First[AbsoluteTiming[#[rows, toDrop]]]} & /@ {f0, f1, f2, f3, f4, f5} // Grid

Mathematica graphics

Equal @@ (#[rows, toDrop] & /@ {f0, f1, f2, f3, f4, f5})

True

kglr
  • 394,356
  • 18
  • 477
  • 896
2

A solution that keeps instead of drops.

toKeep = Select[Range[r], PrimeQ /* Not];
reducedRows = rows[[toKeep]];

Hope this helps.

Edmund
  • 42,267
  • 3
  • 51
  • 143