计算Mathematica中列表所需的不同值

500*_*500 11 wolfram-mathematica count

我想获得List中找到的不同值的数量.

例如:

List的输出为a={1,2,3,4,5}5,而for为2 b={1,1,1,2,2}.

Dr.*_*ius 14

只是为了娱乐,所有以下命令也给出了期望的结果:

Length@Gather@l

Length@Union@l

Length@Tally@l

Count[BinCounts@l, Except@0]

Count[BinLists@l, Except@{}]

Length@Split@Sort@l

Length@GatherBy[l, # &]

Length@Split@SortBy[l, # &]
Run Code Online (Sandbox Code Playgroud)

当然还有更多.

编辑

这是一个小时间实验(不严重)

l = RandomInteger[{1, 10^2}, 10^7];
t2[x_] := {Timing[x], ToString[HoldForm@x]};
SetAttributes[t2, HoldAll]
Grid[Reverse /@
  {t2[Length@DeleteDuplicates[l]],
   t2[Length@Tally[l]],
   t2[Length@Gather[l]],
   t2[Count[BinCounts[l], Except@0]],
   t2[Length@Union[l]],
   t2[Length@Split@Sort@l],
   t2[Count[BinLists[l], Except@0]]},
 Frame -> All]
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

BTW:注意之间的差异BinLists[ ]BinCounts[ ]

编辑

更详细的DeleteDuplicatesvsTally

t = Timing;
ListLinePlot@Transpose@
  Table[l = RandomInteger[{1, 10^i}, 10^7];
   {Log@First@t@Length@DeleteDuplicates@l,
    Log@First@t@Length@Tally@l},
   {i, Range[7]}]
Run Code Online (Sandbox Code Playgroud)

谨防!记录图!

在此输入图像描述


ken*_*ytm 13

使用DeleteDuplicates(或Union旧版本)删除重复元素.然后,您可以计算返回列表中的元素.

In[8]:= Length[DeleteDuplicates[a]]
Out[8]= 5

In[9]:= Length[DeleteDuplicates[b]]
Out[9]= 2
Run Code Online (Sandbox Code Playgroud)


Bre*_*ion 9

Length[DeleteDuplicates[a]]
Run Code Online (Sandbox Code Playgroud)

会做的伎俩.根据你将要做的其他事情,你可以使用UnionTally代替DeleteDuplicates.

  • 值得注意的是,DeleteDuplicates的速度可能是Union的20倍.Union返回排序列表,而DeleteDuplicates将结果值保持原始顺序. (5认同)
  • @Sjoerd,@ Mr.Wizard您观察到的完全是由于数据的包装性质所致.如果我们采用@ Mr的例子`rnd = RandomInteger [999,150000];`并做`rnd [[100000]] = 1/2;`,然后做基准测试,`DeleteDuplicates`仍然更快但只有一个因素大约是`3`,这可能是由于它的线性复杂性与`Union`的`n log n'复杂性相比. (2认同)