# [✓] Pick columns or rows of a matrix?

Posted 1 year ago
1863 Views
|
9 Replies
|
10 Total Likes
|
 I work with random matrices made of 0 and 1. Once generated, I want to remove the columns that contains only zero's. I can easily identify these columns (as a list), and I can remove one column at a time. How to do it in one operation ? Here is how the nb starts: m = 100; n = 10 A = RandomInteger[1, {m, n}] Position [A, Table[0, n]] ...An alternative would be to exclude from the start columns with only zero's. Thanks for suggestions. Pierre Dehez, University of Louvain, Louvain-la-Neuve
Answer
9 Replies
Sort By:
Posted 1 year ago
 You can do the detection and removal at once: m = 100; n = 4 A = RandomInteger[1, {m, n}] Count[A, {0, 0, 0, 0}] A = A /. {0..} :> Nothing Count[A, {0, 0, 0, 0}] Basically, it replaces rows that are made up of only repetitions of 0 with Nothing (if you have an older version substitute Nothing with Sequence[])
Answer
Posted 1 year ago
 Thanks! Elegant. Pierre
Answer
Posted 1 year ago
 You could also use: m = 100; n = 4 A = RandomInteger[1, {m, n}] Position[A, Table[0, n]] Delete[A, %] Delete can accept multiple 'deletions' at the same time…
Answer
Posted 1 year ago
 Even simpler, thanks! I had overlooked the Delete command.
Answer
Posted 1 year ago
 The function DeleteCases could be used. Create a matrix where 0 is twice as likely to occur as 1: In[1]:= matrix = RandomChoice[{50, 25} -> {0, 1}, {20, 3}] Out[1]= {{1, 0, 0}, {0, 0, 0}, {0, 0, 1}, {1, 1, 1}, {0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {0, 0, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 1, 1}, {1, 0, 0}, {1, 1, 0}, {1, 0, 0}, {0, 1, 0}} In[2]:= Length@matrix Out[2]= 20 Then DeleteCases could remove the rows that does not have at least one nonzero element: In[3]:= matrixCleanedOfAllZeroRows = DeleteCases[matrix, {0 ..}] Out[3]= {{1, 0, 0}, {0, 0, 1}, {1, 1, 1}, {1, 0, 0}, {1, 0, 1}, {0, 0,1}, {0, 1, 0}, {0, 0, 1}, {0, 1, 1}, {1, 0, 0}, {1, 1, 0}, {1, 0, 0}, {0, 1, 0}} In[4]:= Length@matrixCleanedOfAllZeroRows Out[4]= 13 
Answer
Posted 1 year ago
 Great also because you suggest a way to produce matrices with few 1's, what I needed.
Answer
Posted 1 year ago
 To sum up, there are at least a dozen ways of doing it, and you can come up with a couple dozen more if one wants… Select[A, Positive@*Total] Select[A, AnyTrue@Positive] Select[A, Not@*AllTrue[PossibleZeroQ]] A /. {0 ..} :> Nothing A /. {0 ..} :> Sequence[] Delete[A, Position[A, Table[0, n]]] Delete[A, Position[A, {0 ..}]] DeleteCases[A, {0 ..}] Cases[A, Except[{0 ..}]] Select[A, MemberQ[1]] Pick[A, Positive@*Total /@ A, True] Pick[A, NoneTrue[Positive] /@ A, False] Reap[Scan[If[MemberQ[#, 1], Sow[#]] &, A]][[2, 1]] Reap[If[MemberQ[#, 1], Sow[#]] & /@ A][[2, 1]] good luck studying them…
Answer
Posted 1 year ago
 I knew that there would be several ways... but not that many. Yet I vote for DeleteCases, most direct. Thanks!
Answer
Posted 1 year ago
 One way to find which columns in a 0/1 matrix mat are zero vectors is to examine Total[mat], which gives the number of ones in each column, or Unitize[Total[mat]], which will be a 0/1 list in which a 0 means the corresponding column is all zeros.If the matrix is mostly zeros, then using SparseArray is worth considering. Here is an example with a random number of ones (5 in the example shown). nn = 10; ones = RandomInteger[{1, 2 nn}]; (* a random number of ones *) mat = SparseArray[RandomInteger[{1, nn}, {ones, 2}] -> 1, {nn, nn}]; mat // MatrixForm The following shows which columns have a one and which no ones at all: TableForm[ Unitize@Total@mat, TableHeadings -> Automatic, TableDirections -> Row ] SparseArray has a built-in method that picks the columns indices of the nonzero entries. They do not necessarily come ordered and there may be repeated indices. We can sort and remove the duplicates with Union. Compare the indices below with the positions of 1 in the table above: Union @@ mat["ColumnIndices"] (* {2, 3, 5, 9, 10} *) We can use these indices to get the columns with at least one 1 with Part and All: newmat = mat[[All, Union @@ mat["ColumnIndices"]]]; newmat // MatrixForm 
Answer
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments