【发布时间】:2011-05-27 15:52:19
【问题描述】:
我想获取列表中不同值的数量。
例如:
a={1,2,3,4,5} 列表的输出为 5,而b={1,1,1,2,2} 的输出为 2。
【问题讨论】:
我想获取列表中不同值的数量。
例如:
a={1,2,3,4,5} 列表的输出为 5,而b={1,1,1,2,2} 的输出为 2。
【问题讨论】:
只是为了娱乐,以下所有命令也给出了预期的结果:
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, # &]
当然还有更多。
编辑
这里是一个计时小实验(不严重)
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]
顺便说一句:注意BinLists[ ] 和BinCounts[ ] 之间的区别
编辑
DeleteDuplicates 与 Tally 的更详细视图
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]}]
小心!日志图!
【讨论】:
DeleteDuplicates[ ] 是最快的 AFAIK。这些只是为了向 OP 展示一些其他方法来做同样的事情。
使用DeleteDuplicates(或旧版本中的Union)删除重复元素。然后,您可以计算返回列表中的元素。
In[8]:= Length[DeleteDuplicates[a]]
Out[8]= 5
In[9]:= Length[DeleteDuplicates[b]]
Out[9]= 2
【讨论】:
Length[DeleteDuplicates[a]]
会成功的。根据您要执行的其他操作,您可以使用Union 或Tally 而不是DeleteDuplicates。
【讨论】:
RandomInteger[999, 150000].
rnd = RandomInteger[999, 150000]; 做rnd[[100000]] = 1/2;,然后做基准测试,DeleteDuplicates 仍然更快,但只有3 的一个因子左右,这可能是由于它的线性复杂度与n log n 的复杂性是 Union。
CountDistinct[a]
也可以,这是 Mathematica 10.0 中引入的一个函数,一个等效于
的函数Length[DeleteDuplicates[a]]
【讨论】: