# Replace elements that do not match a pattern

I have the following matrix

mat={{0,a,b},{c,0,d},{0,0,e}}


I would like to replace the zero elements of it with 1 and the remaining with zero. The first step would be

mat/.{0->1}


However I have not idea how to use the replace operator /. for indicating all the elements that do not match a pattern.

Is it possible to do it?

• What type are the other elements ? Symbols ? Strings ? the pattern should be constructed to match those. Jul 5, 2017 at 10:26
• This will do if the other elements are Symbols. mat /. {0 -> 1, (x_Symbol /; x =!= List) -> 0} Can you guess why we need to exclude List in the pattern ? Jul 5, 2017 at 10:32

## 6 Answers

SetAttributes[rep, Listable]
rep[_] := 0
rep[0] := 1

rep @ mat


{{1, 0, 0}, {0, 1, 0}, {1, 1, 0}}

Update

This method can easily be extended by adding new rules to rep, f.e.:

rep[a_ /; MemberQ[{-t, t, -s, s}, a]] := a


Now

rep @ {{0, a12, s}, {a21, a22, -s}, {t, s, -t}}


{{1, 0, s}, {0, 0, -s}, {t, s, -t}}

• you can also do: rep[a : -t | t | -s | s] := a
– kglr
Jul 5, 2017 at 20:06
• Thanks, always nice to have Alternatives :)
– eldo
Jul 5, 2017 at 20:18
• Thank you so much ! Jul 6, 2017 at 15:24
• You're welcome - and thanks for the accept
– eldo
Jul 6, 2017 at 15:28
Replace[mat, {0 -> 1, _ -> 0}, {2}]
(* or Replace[mat, {0 -> 1, Except[0] -> 0}, {2}] *)


{{1, 0, 0}, {0, 1, 0}, {1, 1, 0}}

Also

1 - Unitize @ ArrayComponents @ mat


{{1, 0, 0}, {0, 1, 0}, {1, 1, 0}}

And a variation of @Lotus's suggestion for ReplaceAll:

mat /. {0 -> 1, Except[List, _Symbol] -> 0}


{{1, 0, 0}, {0, 1, 0}, {1, 1, 0}}

Update: Can this method be generalised to a matrix made of mixed symbols: e.g. {{a11, a12, s}, {a21,a22, -s},{t,s,-t}} and I want to keep only the s and t symbols ...

Replace and ReplaceAll can be used to deal with this case:

mat2 = {{a11, a12, s}, {a21, a22, -s}, {t, s, -t}};

Replace[#, Except[s | t | Times[_, s | t]] :> 0, {2}] & @ mat2


{{0, 0, s}, {0, 0, -s}, {t, s, -t}}

mat2 /. Except[s | t | Times | List, _Symbol] :> 0


{{0, 0, s}, {0, 0, -s}, {t, s, -t}}

• Can this method be generalised to a matrix made of mixed symbols: e.g. {{a11, a12, s}, {a21,a22, -s},{t,s,-t}} and I want to keep only the s and t symbols and remove all the a_{ij}? Jul 5, 2017 at 13:18
• oh man you already did ArrayComponents? So much for my contribution. :^) Jul 5, 2017 at 14:41
• @Galuoises, updated with how the case in your comment can be handled with Replace and ReplaceAll.
– kglr
Jul 5, 2017 at 19:23
• Thank you so much! Jul 6, 2017 at 15:24

Or:

mat={{0,a,b},{c,0,d},{0,0,e}};

Map[If[#===0,1,0]&, mat, {2}]


(* {{1,0,0},{0,1,0},{1,1,0}} *)

mat = {{0, a, b}, {c, 0, d}, {0, 0, e}};

1 - mat/(mat /. 0 -> 1)

{{1, 0, 0}, {0, 1, 0}, {1, 1, 0}}

• Very amusing, thanks. Jul 5, 2017 at 15:33

If the OP will accept a SparseArray:

SparseArray[Position[mat, 0] -> 1, Length@mat] // Normal


{{1, 0, 0}, {0, 1, 0}, {1, 1, 0}}

ReplacePart[mat, {Position[mat, Except[List, _Symbol]] -> 0, Position[mat, 0] -> 1}]
(* {{1, 0, 0}, {0, 1, 0}, {1, 1, 0}} *)