你实际上有两个问题,一个来自标题和隐藏在它后面的问题。第一种是通过回答:
First/@ list
第二个,计数1的游程的数量,已经回答了很多次,但是这种解决方案
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &
比狮子座的解决方案快大约50% 。注意:我增加了测试列表的长度为更好的时机:
largeTestList = RandomInteger[{0, 1}, {10000000}];
Count[Split[largeTestList], {1 ..}] // AbsoluteTiming
Count[Split[largeTestList][[All, 1]], 1] // AbsoluteTiming
Total[Clip[[email protected]#, {0, 1}]] + First[#] &@ largeTestList // AbsoluteTiming
([email protected]@[email protected]# + [email protected]#[[{1, -1}]])/2 &@ largeTestList // AbsoluteTiming
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &@
largeTestList // AbsoluteTiming
Out[680]= {3.4361965, 2498095}
Out[681]= {2.4531403, 2498095}
Out[682]= {0.2710155, 2498095}
Out[683]= {0.2530145, 2498095}
Out[684]= {0.1710097, 2498095}
狮子座的编译攻击后,我正要在认输,但我发现了一个可能的优化,所以开始进入战斗.. [Mr.Wizard,狮子座和我应该在监狱里被抛出干扰对SO和平]
runsOf1Cbis =
Compile[{{lst, _Integer, 1}},
Module[{r = Table[0, {Length[lst] - 1}], i = 1, ctr = First[lst]},
For[i = 2, i <= Length[lst], i++,
If[lst[[i]] == 1 && lst[[i - 1]] == 0, ctr++; i++]];
ctr], CompilationTarget -> "C", RuntimeOptions -> "Speed"]
largeTestList = RandomInteger[{0, 1}, {10000000}];
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &@
largeTestList // AbsoluteTiming
runsOf1C[largeTestList] // AbsoluteTiming
runsOf1Cbis[largeTestList] // AbsoluteTiming
Out[869]= {0.1770101, 2500910}
Out[870]= {0.0960055, 2500910}
Out[871]= {0.0810046, 2500910}
结果各不相同,但我得到10和30%之间的改善。
优化可能很难发现,但如果{0,1}测试成功,则是额外的i++
。在连续的地点你不能有两个。
而且,在这里,我自己的优化优化的列昂尼德的优化优化(我希望这不会拖,或者我要去挨一个堆栈溢出):
runsOf1CDitto =
Compile[{{lst, _Integer, 1}},
Module[{i = 1, ctr = First[lst]},
For[i = 2, i <= Length[lst], i++,
If[lst[[i]] == 1, If[lst[[i - 1]] == 0, ctr++];
i++]];
ctr], CompilationTarget -> "C", RuntimeOptions -> "Speed"]
largeTestList = RandomInteger[{0, 1}, {10000000}];
Total[Clip[ListCorrelate[{-1, 1}, #], {0, 1}]] + First[#] &@
largeTestList // AbsoluteTiming
runsOf1C[largeTestList] // AbsoluteTiming
runsOf1Cbis[largeTestList] // AbsoluteTiming
runsOf1CAlt[largeTestList] // AbsoluteTiming
runsOf1CDitto[largeTestList] // AbsoluteTiming
Out[907]= {0.1760101, 2501382}
Out[908]= {0.0990056, 2501382}
Out[909]= {0.0780045, 2501382}
Out[910]= {0.0670038, 2501382}
Out[911]= {0.0600034, 2501382}
幸运的是,列昂尼德在他的代码中有一个多余的初始化,可以删除。
完美,非常感谢!我试过[All,1]访问子列表,但我无法弄清楚要计数的模式。所以,模式只是1,对吧? –
是的,在这种情况下,模式是文字1. –