Message Boards Message Boards

GROUPS:

[✓] Pick columns or rows of a matrix?

Posted 9 months ago
1180 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

9 Replies

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

Thanks! Elegant. Pierre

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…

Even simpler, thanks! I had overlooked the Delete command.

Posted 9 months 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

Great also because you suggest a way to produce matrices with few 1's, what I needed.

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…

I knew that there would be several ways... but not that many. Yet I vote for DeleteCases, most direct. Thanks!

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 

enter image description here

The following shows which columns have a one and which no ones at all:

TableForm[
 Unitize@Total@mat,
 TableHeadings -> Automatic, TableDirections -> Row
 ]

enter image description here

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

enter image description here

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract