作为my previous question的延续,Simon找到PackedArray列表产品的方法很快,但它不适用于负值。
这可以由Abs
“修复”,但时间损失最小,但是标志丢失了,所以我需要单独找到产品标记。
我尝试过的最快的方法是EvenQ @ Total @ UnitStep[-lst]
lst = RandomReal[{-2, 2}, 5000000];
Do[
EvenQ@Total@UnitStep[-lst],
{30}
] // Timing
Out[]= {3.062, Null}
有更快的方法吗?
答案 0 :(得分:3)
这比你的解决方案快两倍,除了使用Rule@@@
提取相关术语的废话之外,我发现它更清楚 - 它只是用每个符号计算数字元素。
EvenQ[-1 /. Rule@@@Tally@Sign[lst]]
比较时间(和输出)
In[1]:= lst=RandomReal[{-2,2},5000000];
s=t={};
Do[AppendTo[s,EvenQ@Total@UnitStep[-lst]],{10}];//Timing
Do[AppendTo[t,EvenQ[-1/.Rule@@@Tally@Sign[lst]]],{10}];//Timing
s==t
Out[3]= {2.11,Null}
Out[4]= {0.96,Null}
Out[5]= True
答案 1 :(得分:1)
有点迟到的帖子:如果你最终对速度感兴趣,那么使用C编译目标的Compile
似乎比目前发布的最快解决方案快两倍{{1} } - Tally
基于):
Sign
以下是我机器上的计时:
fn = Compile[{{l, _Real, 1}},
Module[{sumneg = 0},
Do[If[i < 0, sumneg++], {i, l}];
EvenQ[sumneg]], CompilationTarget -> "C",
RuntimeOptions -> "Speed"];