Mar*_*zek 12 wolfram-mathematica list duplicates
在Mathematica我有一个列表:
x = {1,2,3,3,4,5,5,6}
Run Code Online (Sandbox Code Playgroud)
如何制作包含重复项的列表?喜欢:
{3,5}
Run Code Online (Sandbox Code Playgroud)
我一直在将Lists视为集合,如果列表中有Except []之类的内容,那么我可以这样做:
unique = Union[x]
duplicates = MyExcept[x,unique]
Run Code Online (Sandbox Code Playgroud)
(当然,如果X将具有两个以上的重复-说,{1,2,2,2,3,4,4-},存在输出将是{2,2,4},但附加的联盟[]会解决这个问题.)
但是没有那样的东西(如果我确实理解了那里的所有功能).
那么,该怎么做?
Wil*_*son 11
有很多方法可以像这样进行列表提取; 这是我想到的第一件事:
Part[Select[Tally@x, Part[#, 2] > 1 &], All, 1]
或者,更可读的部分:
Tally@x Select[%, Part[#, 2] > 1 &] Part[%, All, 1]
它分别给出
{{1, 1}, {2, 1}, {3, 2}, {4, 1}, {5, 2}, {6, 1}}
{{3, 2}, {5, 2}}
{3, 5}
也许你可以想到更有效(在时间或代码空间)的方式 :)
顺便说一句,如果列表未排序,那么您需要先运行Sort它才能运行.
这是一种通过列表单次传递的方法:
collectDups[l_] := Block[{i}, i[n_]:= (i[n] = n; Unevaluated@Sequence[]); i /@ l]
Run Code Online (Sandbox Code Playgroud)
例如:
collectDups[{1, 1, 6, 1, 3, 4, 4, 5, 4, 4, 2, 2}] --> {1, 1, 4, 4, 4, 2}
Run Code Online (Sandbox Code Playgroud)
如果你想要唯一重复的列表 - {1, 4, 2}- 然后将上面的内容包装起来DeleteDuplicates,这是另一个单一的遍历列表(Union效率较低,因为它也会对结果进行排序).
collectDups[l_] :=
DeleteDuplicates@Block[{i}, i[n_]:= (i[n] = n; Unevaluated@Sequence[]); i /@ l]
Run Code Online (Sandbox Code Playgroud)
Will Robertson的解决方案可能更好,因为它更直接,但我认为如果你想要更快速地获得更多,那么这应该会赢.但如果你关心这一点,你就不会在Mathematica中编程!:)
以下是Tally方法的几种更快的变体.
f4 使用Carl Woll和Oliver Ruebenkoenig在MathGroup上给出的"技巧".
f2 = Tally@# /. {{_, 1} :> Sequence[], {a_, _} :> a} &;
f3 = Pick[#, Unitize[#2 - 1], 1] & @@ Transpose@Tally@# &;
f4 = # ~Extract~ SparseArray[Unitize[#2 - 1]]["NonzeroPositions"] & @@ Transpose@Tally@# &;
Run Code Online (Sandbox Code Playgroud)
速度比较(f1包括参考)
a = RandomInteger[100000, 25000];
f1 = Part[Select[Tally@#, Part[#, 2] > 1 &], All, 1] &;
First@Timing@Do[#@a, {50}] & /@ {f1, f2, f3, f4, Tally}
SameQ @@ (#@a &) /@ {f1, f2, f3, f4}
Out[]= {3.188, 1.296, 0.719, 0.375, 0.36}
Out[]= True
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,f4相对于纯粹的几乎没有开销Tally!
| 归档时间: |
|
| 查看次数: |
5600 次 |
| 最近记录: |