In the following matrix m
every 0 should be replaced with a 1:
m = {{0,1,2},{5,0,3},{8,0,0}}
Desired result:
m' = {{1,1,2},{5,1,3},{8,1,1}}
What is the fastest way to do this for a matrix with 200-1000 elements?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communitym + 1 - Unitize[m]
might be faster because it preserves packed arrays, but we'd need a real test.
Unitize
in place of UnitStep
.
$\endgroup$
Oct 24, 2013 at 15:09
Unitize
is the correct function here.
$\endgroup$
Oct 24, 2013 at 15:10
Unitize
is more general and does handle negative numbers.
$\endgroup$
Just for fun: the following hack is even slightly faster than the solution using Unitize
and vectorization, on really large matrices:
replaceZeros[m_?MatrixQ] :=
Normal[
SparseArray[m] /. HoldPattern[SparseArray[s___]] :>
Module[{parts = {s}},
parts[[3]] = 1;
SparseArray @@ parts
]
];
but, in this forms at least, it explicitly uses the fact that elements being replaced are zeros. This is just for fun, in any case.
Unitize
is twice as fast on my PC for 10^7
element matrix.
$\endgroup$
Oct 24, 2013 at 15:36
Unitize
is about 10-20 % slower. Which version of Mathematica you used?
$\endgroup$
Oct 24, 2013 at 15:40
Unitize
.
$\endgroup$
Oct 24, 2013 at 15:47
m = {{0, 1, 2}, {5, 0, 3}, {8, 0, 0}} /. 0 -> 1
{{1, 1, 2}, {5, 1, 3}, {8, 1, 1}}
It's certainly the fastest to write down.
/.
is shorter. Rojo -- habit again. I"m always nervous when a white space means something though, as in: /. 0->1
is OK but /.0->1
is not.
$\endgroup$
Replace[m, 0 -> 1, Infinity]
{{1, 1, 2}, {5, 1, 3}, {8, 1, 1}}
{{0, 1, 2}, {5, 0, 3}, {8, 0, 0}} //. {a___, 0, b___} -> {a, 1, b}
{{1, 1, 2}, {5, 1, 3}, {8, 1, 1}}
For,
RandomInteger[0, {100000, 3}] //. {a___, 0, b___} -> {a, 1, b};
2.62 Sec
RandomInteger[{0, 5}, {10^7, 3}]
$\endgroup$
Oct 24, 2013 at 17:13