How to delete arbitrary numbers of columns from a matrix in mathematica [duplicate]
Correct way to remove matrix columns? (3 answers)
Say I have a matrix of random integers, which is given by
A=RandomInteger[25, {9, 11}]
How can specific columns of this matrix (say 4th and 7th columns) be deleted?
It is really surprising that some people has found this question duplicate. I have asked for two specific columns, but it can be extended to any numbers of columns. Say I have a matrix of (985 x 1123), and I want to delete column no. 18, 37, 54, 85, 305, 564 and 1029 from the original matrix to get a new matrix of size (985 x 1116).
list-manipulation
Soumyajit Roy
Soumyajit RoySoumyajit Roy
$\begingroup$ Delete[Transpose@A, {{4}, {7}}] // Transpose $\endgroup$ – OkkesDulgerci Sep 6 '18 at 12:51
$\begingroup$ mA[[All, Complement[Range[11], {4, 7}]]] $\endgroup$ – Alan Sep 6 '18 at 13:18
I am confused by the complexity of many of these responses. The single command
Drop[A, None, {4,7,3}]
is sufficient to remove columns $4$ and $7$, in steps of $3$ (so as not to remove columms $5$ and $6$). If you wanted to remove more than two columns that are not separated by an equal number of columns, then you would need to use Drop more than once, starting from the rightmost column to be removed; e.g., to remove columns $1$, $3$, and $9$, you could just do
Drop[Drop[A, None, {9}], None, {1,3,2}]
or equivalently,
Drop[Drop[A, None, {3,9,6}], None, {1}]
If you had an arbitrary sorted list of column indices to remove, which we might call c, then Fold[] is trivially applied:
Fold[Drop[#1, None, {#2}]&, A, Reverse[c]]
heropupheropup
$\begingroup$ I considered Drop, but because you cannot give give it an arbitrary list of column indices, I decided that Part is more suited for the job. Especially because repeated calls to Drop is going to be slow for large matrices. $\endgroup$ – Sjoerd Smit Sep 7 '18 at 8:15
I learned this method long time ago from Mr Wizard answer, it works well. But there are many other ways
a = RandomInteger[25, {9, 11}];
a // MatrixForm
ReplacePart[a, {{_, 4}, {_, 7}} :> Sequence[]];
MatrixForm[%]
NasserNasser
$\begingroup$ Some variations on this theme. Mr.Wizard's (## &[]) can be substituted for Sequence[]. In recent versions of Mathematica, substituting Nothing works too. $\endgroup$ – m_goldberg Sep 6 '18 at 17:56
$\begingroup$ Again, my obligatory warning: This method unpacks arrays. $\endgroup$ – Henrik Schumacher Sep 6 '18 at 19:48
The fasted way to do this is to use Part and construct the indices you need to take using Complement:
dropColumns[mat_?MatrixQ, columns : {__Integer}] := With[{
columnsToTake = Complement[
Range[Dimensions[mat][[2]]],
mat[[All, columnsToTake]]
dropColumns[a, {2, 5}] // MatrixForm
OkkesDulgerci
Sjoerd SmitSjoerd Smit
DeleteCol[Matrix_, indexlist_] :=
Block[{internalMatrix = Matrix, i, k = 0,
internallist = SortBy[indexlist, Smaller]},
For[i = 1, i <= Length[internallist], i++,
internalMatrix =
Delete[Transpose[internalMatrix], internallist[[i]] - k];
internalMatrix = Transpose[internalMatrix];
internalMatrix
DeleteCol[A, {4, 7}];
% // MatrixForm
DiogoDiogo
$\begingroup$ How can you delete two or more columns? $\endgroup$ – OkkesDulgerci Sep 6 '18 at 13:25
$\begingroup$ @Okkes Dulgerci now it's possible to delete two or more columns. $\endgroup$ – Diogo Sep 6 '18 at 17:28
Here is another way to do it. I assume that columns you want delete is ordered. i.e. {4,7} will work but {7,4} won't.
SeedRandom@2;
MatrixForm@A
$A=\left( \begin{array}{ccccccccccc} 23 & 3 & 18 & 11 & 10 & 17 & 8 & 3 & 8 & 0 & 19 \\ 9 & 23 & 25 & 24 & 14 & 4 & 3 & 4 & 12 & 12 & 8 \\ 8 & 18 & 6 & 3 & 1 & 14 & 21 & 4 & 14 & 10 & 20 \\ 22 & 8 & 10 & 20 & 19 & 1 & 9 & 12 & 0 & 19 & 11 \\ 25 & 10 & 8 & 7 & 18 & 7 & 9 & 23 & 1 & 6 & 15 \\ 12 & 1 & 0 & 14 & 19 & 12 & 2 & 5 & 3 & 7 & 5 \\ 23 & 24 & 1 & 14 & 3 & 2 & 22 & 16 & 21 & 4 & 11 \\ 4 & 2 & 3 & 20 & 24 & 8 & 10 & 3 & 6 & 12 & 19 \\ 20 & 24 & 6 & 1 & 13 & 10 & 8 & 21 & 5 & 6 & 21 \\ \end{array} \right)$
deleteColumns[mat_?MatrixQ, col_] :=
With[{column = col - Range[0, Length@col - 1]},
Fold[Delete[#, #2] &, Transpose@A, column] // Transpose]
deleteColumns[A, {4, 7, 10}] // MatrixForm
$A=\left( \begin{array}{cccccccc} 23 & 3 & 18 & 10 & 17 & 3 & 8 & 19 \\ 9 & 23 & 25 & 14 & 4 & 4 & 12 & 8 \\ 8 & 18 & 6 & 1 & 14 & 4 & 14 & 20 \\ 22 & 8 & 10 & 19 & 1 & 12 & 0 & 11 \\ 25 & 10 & 8 & 18 & 7 & 23 & 1 & 15 \\ 12 & 1 & 0 & 19 & 12 & 5 & 3 & 5 \\ 23 & 24 & 1 & 3 & 2 & 16 & 21 & 11 \\ 4 & 2 & 3 & 24 & 8 & 3 & 6 & 19 \\ 20 & 24 & 6 & 13 & 10 & 21 & 5 & 21 \\ \end{array} \right)$
OkkesDulgerciOkkesDulgerci
MapThread[Delete, {A, ConstantArray[{{4}, {7}}, Length[A]]}]
Chris DegnenChris Degnen
You can also use a combination of Fold and Drop:
ClearAll[dropCols1]
dropCols1 = Fold[Drop[#, None, #2] &, #, List /@ Reverse @ Sort[#2]] &;
m = Array[Subscript[a, ##] &, {9, 9}];
dropCols1[m, {4, 7}] // MatrixForm // TeXForm
$\small\left( \begin{array}{ccccccc} a_{1,1} & a_{1,2} & a_{1,3} & a_{1,5} & a_{1,6} & a_{1,8} & a_{1,9} \\ a_{2,1} & a_{2,2} & a_{2,3} & a_{2,5} & a_{2,6} & a_{2,8} & a_{2,9} \\ a_{3,1} & a_{3,2} & a_{3,3} & a_{3,5} & a_{3,6} & a_{3,8} & a_{3,9} \\ a_{4,1} & a_{4,2} & a_{4,3} & a_{4,5} & a_{4,6} & a_{4,8} & a_{4,9} \\ a_{5,1} & a_{5,2} & a_{5,3} & a_{5,5} & a_{5,6} & a_{5,8} & a_{5,9} \\ a_{6,1} & a_{6,2} & a_{6,3} & a_{6,5} & a_{6,6} & a_{6,8} & a_{6,9} \\ a_{7,1} & a_{7,2} & a_{7,3} & a_{7,5} & a_{7,6} & a_{7,8} & a_{7,9} \\ a_{8,1} & a_{8,2} & a_{8,3} & a_{8,5} & a_{8,6} & a_{8,8} & a_{8,9} \\ a_{9,1} & a_{9,2} & a_{9,3} & a_{9,5} & a_{9,6} & a_{9,8} & a_{9,9} \\ \end{array} \right)$
dropCols1[m, {4, 7, 1}] // MatrixForm // TeXForm
$\small\left( \begin{array}{cccccc} a_{1,2} & a_{1,3} & a_{1,5} & a_{1,6} & a_{1,8} & a_{1,9} \\ a_{2,2} & a_{2,3} & a_{2,5} & a_{2,6} & a_{2,8} & a_{2,9} \\ a_{3,2} & a_{3,3} & a_{3,5} & a_{3,6} & a_{3,8} & a_{3,9} \\ a_{4,2} & a_{4,3} & a_{4,5} & a_{4,6} & a_{4,8} & a_{4,9} \\ a_{5,2} & a_{5,3} & a_{5,5} & a_{5,6} & a_{5,8} & a_{5,9} \\ a_{6,2} & a_{6,3} & a_{6,5} & a_{6,6} & a_{6,8} & a_{6,9} \\ a_{7,2} & a_{7,3} & a_{7,5} & a_{7,6} & a_{7,8} & a_{7,9} \\ a_{8,2} & a_{8,3} & a_{8,5} & a_{8,6} & a_{8,8} & a_{8,9} \\ a_{9,2} & a_{9,3} & a_{9,5} & a_{9,6} & a_{9,8} & a_{9,9} \\ \end{array} \right)$
Alternatively, (1) assign ##&[] (or Nothing in versions 10+) to the desired columns (dropCols2) or (2) use a combination of MapAt and ##&[]& (dropCols3):
ClearAll[dropCols2, dropCols3]
dropCols2 = Module[{a = #}, a[[All, #2]] = ## &[]; a] &;
dropCols3 = MapAt[## &[] &, #, {{All, #2}}] &;
Equal @@ (#[m, {4, 7}] & /@ {dropCols1, dropCols2, dropCols3})
Equal @@ (#[m, {4, 7, 1}] & /@ {dropCols1, dropCols2, dropCols3})
Not the answer you're looking for? Browse other questions tagged list-manipulation or ask your own question.
Correct way to remove matrix columns?
Delete rows based on specific periods
How to delete duplicates of certain values in list of lists in a specific column of all sublists?
Creating a random matrix of no duplicates in both row and column from a given set list of elements
Changing the position of rows and columns in a matrix
Delete elements less than the last largest element