How to delete arbitrary numbers of columns from a matrix in mathematica [duplicate]

How to delete arbitrary numbers of columns from a matrix in mathematica [duplicate]



This question already has an answer here:



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?



EDIT



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).



This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.





$begingroup$
Delete[Transpose@A, 4, 7] // Transpose
$endgroup$
– Okkes Dulgerci
Sep 6 '18 at 12:51


Delete[Transpose@A, 4, 7] // Transpose





$begingroup$
mA[[All, Complement[Range[11], 4, 7]]]
$endgroup$
– Alan
Sep 6 '18 at 13:18


mA[[All, Complement[Range[11], 4, 7]]]




7 Answers
7



I am confused by the complexity of many of these responses. The single command



Drop[A, None, 4,7,3]


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[Drop[A, None, 9], None, 1,3,2]


Drop[Drop[A, None, 9], None, 1,3,2]



or equivalently,



Drop[Drop[A, None, 3,9,6], None, 1]


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:


c


Fold



Fold[Drop[#1, None, #2]&, A, Reverse[c]]


Fold[Drop[#1, None, #2]&, A, Reverse[c]]





$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



Drop


Part


Drop



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



Mathematica graphics


ReplacePart[a, _, 4, _, 7 :> Sequence];
MatrixForm[%]



Mathematica graphics





$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


(## &)


Sequence


Nothing





$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:


Part


Complement


dropColumns[mat_?MatrixQ, columns : __Integer] := With[
columnsToTake = Complement[
Range[Dimensions[mat][[2]]],
columns
]
,
mat[[All, columnsToTake]]
];
a = RandomInteger[25, 9, 11];
a // MatrixForm
dropColumns[a, 2, 5] // MatrixForm


A = RandomInteger[25, 9, 11];
A // MatrixForm
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];
k++;
];
internalMatrix
];
DeleteCol[A, 4, 7];
% // MatrixForm
DeleteCol[A, 7, 4];
% // MatrixForm





$begingroup$
How can you delete two or more columns?
$endgroup$
– Okkes Dulgerci
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.


4,7


7,4


SeedRandom@2;
A = RandomInteger[25, 9, 11];
MatrixForm@A



$A=left(
beginarrayccccccccccc
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 \
endarray
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(
beginarraycccccccc
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 \
endarray
right)$


MapThread[Delete, A, ConstantArray[4, 7, Length[A]]]



You can also use a combination of Fold and Drop:


Fold


Drop


ClearAll[dropCols1]
dropCols1 = Fold[Drop[#, None, #2] &, #, List /@ Reverse @ Sort[#2]] &;



Examples:


m = Array[Subscript[a, ##] &, 9, 9];

dropCols1[m, 4, 7] // MatrixForm // TeXForm



$smallleft(
beginarrayccccccc
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 \
endarray
right)$


dropCols1[m, 4, 7, 1] // MatrixForm // TeXForm



$smallleft(
beginarraycccccc
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 \
endarray
right)$



Alternatively, (1) assign ##& (or Nothing in versions 10+) to the desired columns (dropCols2) or (2) use a combination of MapAt and ##&& (dropCols3):


##&


Nothing


dropCols2


MapAt


##&&


dropCols3


ClearAll[dropCols2, dropCols3]
dropCols2 = Module[a = #, a[[All, #2]] = ## &; a] &;
dropCols3 = MapAt[## & &, #, All, #2] &;

Equal @@ (#[m, 4, 7] & /@ dropCols1, dropCols2, dropCols3)



True


Equal @@ (#[m, 4, 7, 1] & /@ dropCols1, dropCols2, dropCols3)



True

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)