1
$\begingroup$

Given a list (e.g. of integers) x and a list of 0s and 1s i (of the same length as x), how can I alter those entries of x where the value of i is 1?

For example, the code

n=10^8; x=RandomInteger[{-100,100},n]; i=RandomInteger[{0,1},n];
y=RandomInteger[{-100,100},n]; ByteCount@{x,i,y}
AbsoluteTiming@MaxMemoryUsed[i=Flatten[Position[i,1],1]]
AbsoluteTiming@MaxMemoryUsed[x[[i]]=y[[i]]]

shows that for 2.4GB of data, Position spends 22sec and 10GB, whilst assignment spends only 0.85sec and 0.8GB. The former seems excessive. Is there a better way to do this? Python has this built-in (when i is a numpy array of booleans).

$\endgroup$
4
  • $\begingroup$ why not just x = x (1 - i)? $\endgroup$
    – kglr
    Oct 7 '20 at 18:45
  • 2
    $\begingroup$ x[[Pick[Range@n,i,1]]=0 Code Wolfram like Wolfram, not Python, else it's Cobols all the way down... $\endgroup$
    – ciao
    Oct 7 '20 at 19:00
  • $\begingroup$ @kglr Uf, you're right, x=x*(1-i)+y*i. However, this only works if y is of the same length as x. But what if the length of y is the number of ones in i and I want to do x[[i]]=y? $\endgroup$
    – Leo
    Oct 7 '20 at 19:10
  • $\begingroup$ @Leo, posted the comment as an answer. $\endgroup$
    – kglr
    Oct 7 '20 at 19:43
1
$\begingroup$
n = 10^8; x = RandomInteger[{-100, 100}, n]; i = RandomInteger[{0, 1}, n];
z1 = z2 = z3 = x;

AbsoluteTiming @ MaxMemoryUsed[z1 = z1 (1 - i)]
{2.00115, 1600000424}
AbsoluteTiming @ MaxMemoryUsed[z3[[Random`Private`PositionsOf[i, 1]]] = 0]
{3.52455, 1599995920}
AbsoluteTiming @ MaxMemoryUsed[z2[[Pick[Range @ n, i, 1]]] = 0] (* ciao's comment*)
{4.8352, 1655914552}
z1 == z2 == z3
True

The last two also work for the case where "the length of y is the number of ones in i and I want to do x[[i]] = y".

$\endgroup$
2
  • $\begingroup$ Much appreciated! Just one more question: if Position and RandomPrivatePositionsOf do the same thing, but the latter is way more effective, why doesn't it replace the former as an official command? $\endgroup$
    – Leo
    Oct 7 '20 at 20:45
  • 1
    $\begingroup$ @Leo, Position handles arbitrary inputs' Random`Private`PositionsOf (seems to be ) limited to integer vectors. $\endgroup$
    – kglr
    Oct 7 '20 at 21:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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