I start off with m = 1000 x 5
matrix, and I would like to remove first column to get 1000 x 4
matrix and repeat again for 1000 x 3
and so on. Is there an efficient way to do this? I see Insert to add columns or rows but don't see command for removing? I see maybe use the extract but is this only for a single vector extraction?
3 Answers
As has been shown there are a number of ways to do this. To summarize:
m = RandomInteger[9, {6, 4}]
All of these:
Drop[m, 0, 1]
Rest /@ m
m[[All, 2 ;;]]
{##2} & @@@ m
Produce:
Each has a place. For the specific operation Rest
is especially clear. Drop
can easily drop columns besides the first, e.g. Drop[m, 0, {3}]
, and it is very fast. Part
is also usually very fast, and allows assignments which is both flexible and efficient (when applicable). SlotSequence
is simply fun and can be quite useful when you also want to do something with the elements.
Timings with larger matrix:
m = RandomInteger[9, {15000, 100}];
Drop[m, 0, 1] // timeAvg
Rest /@ m // timeAvg
m[[All, 2 ;;]] // timeAvg
{##2} & @@@ m // timeAvg
0.0010224
0.004496
0.0011728
0.03992
(The timeAvg
function has been repeatedly posted before. Use Search.)
-
1$\begingroup$ I believe the currently documented syntax is
Drop[m,None,1]
rather thanDrop[m,0,1]
. If so, I'm wondering if that means the use of a0
instead is guaranteed to work (lookin forward). $\endgroup$– AlanOct 2, 2016 at 12:34 -
1$\begingroup$ @Alan This has worked for a long time and I wouldn't expect it to go away. Unfortunately the Mathematica documentation is not rigorous and one must fill in the gaps with experimentation and inference. I would say that
Drop[m, 0, 1]
is pseudo-documented by "n (is) elements 1 through n" and the convention with other functions that "one through zero" is an empty set, i.e.Range[0]
returns{}
. Note thatDrop[m, {}, 1]
also works. If you are hoping to see all of this specified explicitly in the documentation forDrop
I am afraid you will be disappointed. :-/ $\endgroup$ Oct 2, 2016 at 13:12
I am not sure this deserves a full blown answer but...
a = RandomVariate[NormalDistribution[], {15, 5}];
Rest /@ a // Dimensions
(* {15,4} *)
And to operate recursively
Dimensions /@ NestList[Rest /@ # &, a, 3]
(*
15 5
15 4
15 3
15 2
*)
EDIT
Replaced Most
by Rest
since as noticed by Mr Wizard this was actually the OP question!
-
$\begingroup$ In truth, this is one of those canonical questions that has several approaches. $\endgroup$– rcollyerDec 27, 2012 at 16:48
-
$\begingroup$ Why not continue the process?
NestList[Most /@ # &, a, 5]
Then look atDimensions /@ NestList[Most /@ # &, a, 5]
, whose output is{{15, 5}, {15, 4}, {15, 3}, {15, 2}, {15, 1}, {15, 0}}
, as expected. But look at:MatrixForm /@ NestList[Most /@ # &, a, 5]
. I find the final entry in the output of that surprising: I would expect to see just the big 15-row brackets with nothing inside them; instead, I see an empty list{}
in each of the 15 rows. $\endgroup$– murrayDec 27, 2012 at 17:12
Here is a way to do it with Table
:
mat = RandomReal[{0, 1}, {3, 5}]
Table[mat = mat[[All, 2 ;; -1]], {Dimensions[mat][[2]] - 1}];
MatrixForm /@ %
-
1$\begingroup$ +1 for an efficient mutable method. Of note is that one can use the slightly shorter
mat[[All, 2 ;;]]
. $\endgroup$ Dec 28, 2012 at 14:18
Most
? $\endgroup$