4
$\begingroup$

Given a (rectangular) matrix of integers, i.e.

RandomInteger[4, {10, 3}] 

I want to apply the following rules only to the last column

rules = {0 -> 1000 ,1-> 11, 2-> 22, 3 -> 33, 4-> 44}

So for example if

mat = RandomInteger[4, {10, 3}] 

is

{{2, 1, 0}, {3, 0, 1}, {4, 2, 1}, {2, 0, 3}, {1, 0, 0}, {0, 0, 1}, {3, 3, 2}, {0, 2, 1}, {0, 1, 1}, {2, 1, 2}}

Then the code I use is

Flatten@{Most[##], Last[#] /. rules} & /@ mat

{{2, 1, 1000}, {3, 0, 11}, {4, 2, 11}, {2, 0, 33}, {1, 0, 1000}, {0, 0, 11}, {3, 3, 22}, {0, 2, 11}, {0, 1, 11}, {2, 1, 22}}

Any better code appreciated

$\endgroup$

8 Answers 8

9
$\begingroup$
mat = {{2, 1, 0}, {3, 0, 1}, {4, 2, 1}, {2, 0, 3}, {1, 0, 0}, {0, 0, 1},
       {3, 3, 2}, {0, 2, 1}, {0, 1, 1}, {2, 1, 2}};
rules = {0 -> 1000 ,1-> 11, 2-> 22, 3 -> 33, 4-> 44};

mat[[All, -1]] = mat[[All, -1]] /. rules; mat
(* {{2, 1, 1000}, {3, 0, 11}, {4, 2, 11}, {2, 0, 33}, {1, 0, 1000}, 
    {0,  0, 11}, {3, 3, 22}, {0, 2, 11}, {0, 1, 11}, {2, 1, 22}} *)

or

MapAt[# /. rules &, mat, {{All, -1}}]
(* same output *)

or, changing the rules (as in @Pickett's answer) -- not to another rule, but -- to a function,

ClearAll[f];
(f[x__, #] := {x, #2}) & @@@ rules;
f[x__] := {x};
f @@@ mat
(* same output *)
$\endgroup$
3
$\begingroup$

If the rule doesn't fit, change it:

rules = {a_, b_, #} :> {a, b, #2} & @@@ {0 -> 1000, 1 -> 11, 2 -> 22, 3 -> 33, 4 -> 44};
mat /. rules

{{4, 4, 1000}, {4, 1, 1000}, {1, 2, 33}, {3, 1, 1000}, {2, 0, 33}, {4,3, 33}, {2, 1, 11}, {2, 0, 44}, {3, 3, 22}, {1, 2, 22}}

$\endgroup$
3
$\begingroup$
With[{m = Transpose[mat]}, Transpose[Append[Most[m], Last[m]/. rules]]]
$\endgroup$
3
$\begingroup$
mat[[All, -1]] = Transpose[mat][[-1]] /. rules; mat
{{2, 1, 1000}, {3, 0, 11}, {4, 2, 11}, {2, 0, 33}, {1, 0, 1000}, {0, 0, 11}, {3, 3, 22},
 {0, 2, 11}, {0, 1, 11}, {2, 1, 22}}
$\endgroup$
3
$\begingroup$

Here are a couple of ways:

Cases[mat, {e__, l_} :> {e, l /. rules}]

or

ReplacePart[mat, {i_, 3} :> (mat[[i, 3]] /. rules)]
$\endgroup$
2
$\begingroup$
data = RandomInteger[4, {10, 3}];
rules = {0 -> 1000, 1 -> 11, 2 -> 22, 3 -> 33, 4 -> 44};

data /. {a__?NumberQ, b_} :> {a, b /. rules} // MatrixForm

enter image description here

$\endgroup$
1
$\begingroup$

ReplaceAt, introduced with V 13.1, is an ideal candidate for this task:

mat = {{2, 1, 0}, {3, 0, 1}, {4, 2, 1}, {2, 0, 3}, {1, 0, 0}, {0, 0, 1}, {3, 3, 2}, {0, 2, 1}, {0, 1, 1}, {2, 1, 2}};

rules = {0 -> 1000, 1 -> 11, 2 -> 22, 3 -> 33, 4 -> 44};

ReplaceAt[mat, rules, {All, -1}] // MatrixForm

enter image description here

$\endgroup$
1
$\begingroup$

Using Lookup:

amat = {{2, 1, 0}, {3, 0, 1}, {4, 2, 1}, {2, 0, 3}, {1, 0, 0}, {0, 0, 
   1}, {3, 3, 2}, {0, 2, 1}, {0, 1, 1}, {2, 1, 2}}

rules = {0 -> 1000, 1 -> 11, 2 -> 22, 3 -> 33, 4 -> 44}

(bmat = Join[
    Most /@ amat
    , Lookup[rules, {#}, {#}] & /@ Last /@ amat, 2]
  ) // MatrixForm

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.