I would like to know is it possible to find positions of False
in t
:
t = Table[RandomChoice[{True, False}], 6000];
Flatten[Position[t, False]] // AbsoluteTiming
faster than the above method. I will appreciate any help.
Speed here is hindered by the fact that True
/False
is not a packable type in Mathematica, although I personally think it should be.
If it is possible to reformulate your problem to use 1
/0
instead, which can be packed, the methods already provided (Pick
and SparseArray
) each become much faster.
You can convert your data using With
faster than using Boole
, but the overhead is still significant:
SeedRandom[1]
t = Table[RandomChoice[{True, False}], 6000];
b = Developer`ToPackedArray @
With[{True = 1, False = 0}, Evaluate @ t]; // RepeatedTiming
{0.000151, Null}
Now observe how fast Pick
becomes compared to its direct application on t
:
r1 = Pick[Range @ Length @ t, t, False]; // RepeatedTiming
r2 = Pick[Range @ Length @ b, b, 0]; // RepeatedTiming
r1 === r2
{0.000343, Null} {0.0000509, Null} True
Combined with the overhead of the conversion this is a little slower than kglr's method (0.000176 second on my machine), but it gives an idea of the performance that is possible if you can avoid True
/False
and use packed integers instead.
With[{True = 1, False = 0}, Evaluate @ t]
is faster than Boole
.
$\endgroup$
Commented
Aug 10, 2018 at 6:54
You can use Pick
:
t = Table[RandomChoice[{True,False}],6000];
r1 = Flatten[Position[t,False]]; //RepeatedTiming
r2 = Pick[Range@Length@t,t,False]; //RepeatedTiming
r1 === r2
{0.0023, Null}
{0.00036, Null}
True
Another useful alternative is PositionIndex
, especially when you want to know the positions of different values:
r3 = PositionIndex[t]; //RepeatedTiming
r1 === r2 === r3[False]
{0.00070, Null}
True
Using SparseArray
with "AdjacencyLists"
or with "NonzeroPositions"
is faster than alternatives posted so far:
SeedRandom[1]
t = Table[RandomChoice[{True, False}], 6000];
r4 =SparseArray[t, Automatic, True]["AdjacencyLists"]; //RepeatedTiming // First
0.00021
r5 = Flatten@SparseArray[t, Automatic, True]["NonzeroPositions"]; //RepeatedTiming// First
0.00021
versus
r1 = Flatten[Position[t, False]]; // RepeatedTiming // First
0.0027
r2 = Pick[Range @ Length @ t, t, False]; // RepeatedTiming // First
0.000414
r3 = PositionIndex[t][False]; // RepeatedTiming // First
0.000830
(b = Developer`ToPackedArray @ With[{True =1, False =0}, Evaluate @ t];
r6 = Pick[Range @ Length @ b, b, 0];) //RepeatedTiming // First
0.00028
SameQ[r1, r2, r3, r4, r5, r6]
True
where r1
is from OP, r2
and r3
are from Carl Woll's and r6
is from Mr.Wizard's answer.