Imagine we have:
a = RandomInteger[1, {50, 150, 53}];
b = RandomInteger[1, {50, 150, 53}];
mask = RandomInteger[1, {50, 150, 53}];
How do I replace a(mask) with b(mask)?
One way to do this when a and b may contain any kind of symbolic expression could be
With[{pos = Position[mask, 1]},
ReplacePart[a, Thread[pos -> Extract[b, pos]]]
]
Here, first you get the positions at which mask contains 1. Then, you replace every part of a at these positions with the corresponding entry of b at this position.
Assuming a, b, and mask only contain 0 or 1 you can use the much faster solution:
a - BitAnd[a, mask] + BitAnd[b, mask]
or, even faster:
BitOr[BitAnd[a, BitNot[mask]], BitAnd[b, mask]]
Here are the timings in comparison:
a - BitAnd[a, mask] + BitAnd[b, mask] // RepeatedTiming // First
(* 0.012 *)
BitOr[BitAnd[a, BitNot[mask]], BitAnd[b, mask]] // RepeatedTiming // First
(* 0.0075 *)
the latter being even faster than @Shadowray's solution:
(b - a)*mask + a // RepeatedTiming // First
(* 0.0098 *)
If mask may contain only zeros and ones, then you can do such assignment arithmetically:
(b - a)*mask + a
Since arithmetic operations on arrays are highly optimized, this solution should be quite fast:
(b - a)*mask + a; // RepeatedTiming // First
0.000885
a = ConstantArray[ 1, {2, 3}]; b = {{1, 1, 1}, {0, 0, 0}}; mask = {{1, 0, 0}, {0, 1, 1}};
$\endgroup$
a and b)
$\endgroup$