6
$\begingroup$

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?

$\endgroup$
7
  • 1
    $\begingroup$ toDrop = Transpose[{Select[Range[r], PrimeQ]}] $\endgroup$
    – ciao
    May 20, 2016 at 19:04
  • 6
    $\begingroup$ Have you tried Delete[rows, List /@ toDrop]? $\endgroup$ May 20, 2016 at 19:10
  • $\begingroup$ 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. $\endgroup$
    – Mr.Wizard
    May 20, 2016 at 20:26
  • $\begingroup$ Also related (StackOverflow): Efficient way to pick/delete a list of rows/columns in a matrix in Mathematica $\endgroup$
    – user1066
    May 21, 2016 at 14:29
  • $\begingroup$ @J.M.: Would you kindly post your comment as an answer? $\endgroup$
    – kjo
    May 21, 2016 at 17:19

3 Answers 3

8
$\begingroup$

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

$\endgroup$
0
10
$\begingroup$

Probably the simplest way will be:

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

A solution that keeps instead of drops.

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

Hope this helps.

$\endgroup$

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.