# Looking for a better way to delete an arbitrary list of rows from a matrix

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]

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?

• toDrop = Transpose[{Select[Range[r], PrimeQ]}]
– ciao
May 20, 2016 at 19:04
• Have you tried Delete[rows, List /@ toDrop]? May 20, 2016 at 19:10
• Despite acknowledgement of Complement I feel that this problem is already described in other questions: (17002), (20228), (43785), (108336). Note that the answers below largely duplicate methods already given in answer to these. I shall probably mark this as a duplicate unless someone makes a compelling argument against that. May 20, 2016 at 20:26
• Also related (StackOverflow): Efficient way to pick/delete a list of rows/columns in a matrix in Mathematica May 21, 2016 at 14:29
– kjo
May 21, 2016 at 17:19

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

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

True

Probably the simplest way will be:

reducedRows = ReplacePart[rows, Transpose[{toDrop}] -> Nothing[]]
• I believe you need to do List /@ toDrop -> Nothing[]. (Cant verify with 10.1 though) May 20, 2016 at 20:01
• @george2079 - oops, copied wrong - fixed (Transpose faster than map List)
– ciao
May 20, 2016 at 20:05
• (+1) because I've learned Nothing.
– Jens
May 20, 2016 at 21:25
• I didn't know Nothing as well, I was using ##&[] instead. I'll do a find and replace in all my code ! May 21, 2016 at 13:45
• I fixed the Transpose correction. Also you don't need Nothing[], Nothing only works. May 21, 2016 at 13:54

A solution that keeps instead of drops.

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

Hope this helps.