12

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

Soumyajit Roy
  • 684
  • 3
  • 12

7 Answers7

11

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

Nasser
  • 143,286
  • 11
  • 154
  • 359
9

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]]],
     columns
   ]
 },
    mat[[All, columnsToTake]]
];
a = RandomInteger[25, {9, 11}];
a // MatrixForm
dropColumns[a, {2, 5}] // MatrixForm
OkkesDulgerci
  • 10,716
  • 1
  • 19
  • 38
Sjoerd Smit
  • 23,370
  • 46
  • 75
5
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 
Stratus
  • 2,942
  • 12
  • 24
5

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]]

heropup
  • 2,092
  • 13
  • 12
  • 2
    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. – Sjoerd Smit Sep 07 '18 at 08:15
4

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;
    A = RandomInteger[25, {9, 11}];
    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)$

OkkesDulgerci
  • 10,716
  • 1
  • 19
  • 38
3
MapThread[Delete, {A, ConstantArray[{{4}, {7}}, Length[A]]}]
Chris Degnen
  • 30,927
  • 2
  • 54
  • 108
3

You can also use a combination of Fold and 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

$\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})

True

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

True

kglr
  • 394,356
  • 18
  • 477
  • 896