正如@High Performance Mark 和@Nicholas Wilson 所说,我首先通过以下方式将两个列表组合在一起Transpose
or Thread
。在这种情况下,
In[1]:= Transpose[{clusterIndices, points}]==Thread[{clusterIndices, points}]
Out[1]:= True
有一次,我看了一下哪个更快,我想Thread
稍微快一些。但是,只有当您使用很长的列表时,它才真正重要。
@High Performance Mark 提出了很好的建议Select
。但是,它一次只允许您拉出一个集群。选择簇1的代码如下:
Select[Transpose[{clusterIndices, points}], #[[1]]==1& ][[All, All, 2]]
由于您似乎想要生成所有集群,因此我建议执行以下操作:
GatherBy[Transpose[{clusterIndices, points}], #[[1]]& ][[All, All, 2]]
它的优点是作为一个衬垫,唯一棘手的部分是选择正确的Part
结果列表中。确定多少的技巧All
条款是必要的,需要注意的是
Transpose[{clusterIndices, points}][[All,2]]
需要将点从转置列表中取出。但是,“聚集”列表还有一个附加级别,因此是第二个All
.
需要注意的是,第二个参数GatherBy
是一个接受一个参数的函数,它可以与您想要使用的任何函数互换。因此,它非常有用。但是,如果您想在收集数据时转换数据,我会看看Reap
and Sow
.
Edit: Reap
and Sow
有点未被充分利用,但相当强大。它们使用起来有点令人困惑,但我怀疑GatherBy
是在内部使用它们来实现的。例如,
Reap[ Sow[#[[2]], #[[1]] ]& /@ Transpose[{clusterIndices, points}], _, #2& ]
与我之前的代码执行相同的操作,而无需从点中删除索引。本质上,Sow
用索引标记每个点,然后 Reap 收集所有标签(_
对于第二个参数)并仅输出点。就我个人而言,我使用它而不是 GatherBy,并将其编码到我加载的函数中,如下所示:
SelectEquivalents[x_List,f_:Identity, g_:Identity, h_:(#2&)]:=
Reap[Sow[g[#],{f[#]}]&/@x, _, h][[2]];
注意:此代码是 5.x 中帮助文件中内容的修改形式。但是,6.0 和 7.0 帮助文件删除了很多有用的示例,这就是其中之一。