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?
m + 1 - Unitize[m]
might be faster because it preserves packed arrays, but we'd need a real test.
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 about 10-20 % slower. Which version of Mathematica you used?
– Leonid Shifrin
Oct 24 '13 at 15:40
Unitize.
– Leonid Shifrin
Oct 24 '13 at 15:47
Random generator to only 0 and 1) and every time, Unitize is at least twice as fast on my machine.
– RunnyKine
Oct 24 '13 at 15:50
SparseArray[m, Automatic, toBeReplaced], instead.
– rcollyer
Oct 24 '13 at 16:35
SparseArray to achieve its goals. But I like it.
– Leonid Shifrin
Oct 24 '13 at 16:41
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.
– bill s
Oct 24 '13 at 14:58
{{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
Unitizein place ofUnitStep. – Leonid Shifrin Oct 24 '13 at 15:09Unitizeis the correct function here. – RunnyKine Oct 24 '13 at 15:10Unitizeis more general and does handle negative numbers. – bill s Oct 24 '13 at 15:13