根据Mathematica中的另一个列表值拆分列表

在Mathematica中,我有一个点坐标列表

size = 50;
points = Table[{RandomInteger[{0, size}], RandomInteger[{0, size}]}, {i, 1, n}];

以及这些点属于的聚类索引列表

clusterIndices = {1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1};

根据clusterIndices值将点分成两个单独的列表最简单的方法是什么?

编辑:我想出了解决方案:

pointIndices =
  Map[#[[2]] &,
    GatherBy[MapIndexed[{#1, #2[[1]]} &, clusterIndices], First],
    {2}];
pointsByCluster = Map[Part[points, #] &, pointIndices];

有没有更好的方法来做到这一点?


这个怎么样?

points[[
    Flatten[Position[clusterIndices, #]]
    ]] & /@
 Union[clusterIndices]

正如@High Performance Mark和@Nicholas Wilson所说的那样,我会先通过TransposeThread将两个列表结合在一起。 在这种情况下,

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中的第二个参数是一个接受一个参数的函数,它可以与您希望使用的任何函数互换。 因此,这非常有用。 但是,如果您希望在收集数据时转换数据,那么我会考虑ReapSow

编辑: ReapSow有些在使用,并且相当强大。 他们使用起来有些困惑,但我怀疑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帮助文件删除了很多有用的例子,这是其中之一。


这里有一个简洁的方法来使用版本7.0中新的SplitBy函数来实现这一点,该函数应该非常快:

SplitBy[Transpose[{points, clusterIndices}], Last][[All, All, 1]]

如果你不使用7.0,你可以这样实现:

Split[Transpose[{points, clusterIndices}], Last[#]==Last[#2]& ][[All, All, 1]]

更新

对不起,我没有看到你只想要两个组,我认为这是聚类,而不是分裂。 这里有一些代码:

FindClusters[Thread[Rule[clusterIndices, points]]]
链接地址: http://www.djcxy.com/p/35497.html

上一篇: Splitting a list based on another list values in Mathematica

下一篇: How to close initialization cell in Notebook?