Wolfram mathematica 正确使用Mathematica收集/收集

Wolfram mathematica 正确使用Mathematica收集/收集,wolfram-mathematica,Wolfram Mathematica,如何使用Mathematica的收集/收集/转置函数转换: { { {1, foo1}, {2, foo2}, {3, foo3} }, { {1, bar1}, {2, bar2}, {3, bar3} } } 到 编辑:谢谢!我希望有一个简单的方法,但我想不是 以下是您的列表: tst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}} 这里有一个方法: In[84]:= Flatten/

如何使用Mathematica的收集/收集/转置函数转换:

{ { {1, foo1}, {2, foo2}, {3, foo3} }, { {1, bar1}, {2, bar2}, {3, bar3} } } 

编辑:谢谢!我希望有一个简单的方法,但我想不是

以下是您的列表:

tst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3,  bar3}}}
这里有一个方法:

In[84]:= 
Flatten/@Transpose[{#[[All,1,1]],#[[All,All,2]]}]&@
  GatherBy[Flatten[tst,1],First]

Out[84]= {{1,foo1,bar1},{2,foo2,bar2},{3,foo3,bar3}}
编辑

这是一个完全不同的版本,只是为了好玩:

In[106]:= 
With[{flat = Flatten[tst,1]},
   With[{rules = Dispatch[Rule@@@flat]},
       Map[{#}~Join~ReplaceList[#,rules]&,DeleteDuplicates[flat[[All,1]]]]]]

Out[106]= {{1,foo1,bar1},{2,foo2,bar2},{3,foo3,bar3}}
编辑2

这里还有另一种方法,使用链表和内部函数来累积结果:

In[113]:= 
Module[{f},f[x_]:={x};
  Apply[(f[#1] = {f[#1],#2})&,tst,{2}];
  Flatten/@Most[DownValues[f]][[All,2]]]

Out[113]= {{1,foo1,bar1},{2,foo2,bar2},{3,foo3,bar3}}
编辑3

OK,对于那些认为所有这些都过于复杂的人来说,这里有一个非常简单的基于规则的解决方案:

In[149]:= 
GatherBy[Flatten[tst, 1], First] /. els : {{n_, _} ..} :> {n}~Join~els[[All, 2]]

Out[149]= {{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}}

可能有点过于复杂,但是:

lst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}}

Map[
    Flatten,
    {Scan[Sow[#[[1]]] &,
                Flatten[lst, 1]] // Reap // Last // Last // DeleteDuplicates,
    Scan[Sow[#[[2]], #[[1]]] &,
            Flatten[lst, 1]] // Reap // Last} // Transpose
]
(*
{{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}}
*)
下面是它的工作原理:

Scan[Sow[#[[1]]] &,
    Flatten[lst, 1]] // Reap // Last // Last // DeleteDuplicates
返回每个列表项的唯一第一个元素,按照它们的排列顺序(因为
DeleteDuplicates
从不重新排列元素)。那么

利用
eaw
在不同列表中返回带有不同标记的表达式这一事实。然后把它们放在一起,转置

这样做的缺点是我们扫描两次

编辑:

这个

速度(非常)稍快,但可读性更低……

可能更容易:

tst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3,  bar3}}};

GatherBy[Flatten[tst, 1], First] /. {{k_, n_}, {k_, m_}} -> {k, n, m}
(*
-> {{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}}
*)

MapThread

如果“Fo”和“bar”子列表被保证彼此对齐(如示例中所示),并且如果您将考虑使用除<代码> >集合> <代码> >代码>收藏> /代码> />代码>转置,则<>代码> MultPosith >就足够了:

data={{{1,foo1},{2,foo2},{3,foo3}},{{1,bar1},{2,bar2},{3,bar3}}};

MapThread[{#1[[1]], #1[[2]], #2[[2]]}&, data]
结果:

{{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}}
模式匹配

如果列表没有对齐,您也可以使用直接模式匹配和替换(尽管我不建议对大型列表使用这种方法):

播种/收获

对于未对齐的列表,更有效的方法是使用
Sow
Reap

Reap[Cases[data, {x_, y_} :> Sow[y, x], {2}], _, Prepend[#2, #1] &][[2]]
也只是为了好玩

DeleteDuplicates /@ Flatten /@ GatherBy[Flatten[list, 1], First]
在哪里

编辑

更多的乐趣

Gather[#][[All, 1]] & /@ Flatten /@ GatherBy[#, First] & @ 
 Flatten[list, 1]

下面是我将如何使用我发布的SelectEquivalents版本来实现这一点


这种方法非常通用。我以前常常使用GatherBy之类的函数来处理我在蒙特卡罗模拟中生成的巨大列表。现在,使用SelectEquivalents,此类操作的实现更加直观。另外,它是基于收获和播种的组合,这在Mathematica中非常快。

在问题更新为更明确和具体之前,我将假设我想要的,并提出以下建议:

UnsortedUnion @@@ #~Flatten~{2} &

请参阅:

直到上次编辑,我才看到您的解决方案。我的想法是一样的,但我花了一些时间来解决的主要问题是在基于规则的方法中处理子列表中任意数量的术语-您只处理两个术语。@Leonid您是对的,但我不确定编辑3中的问题中是否要求这样的概括,
els:
是什么意思?这是一种命名模式的方法吗?@David:standard
x_
实际上是
x:
的缩写,但前者太常见了,以至于很多人都不认识后者。两者都是“名为
x
的模式匹配
Blank[]
”@Simon您的解释是有道理的。谢谢。IMHO功能需求本来可以写得更好一些。你的例子有很多值得猜测的地方。是的,请更新问题使其更具体。目前它是相当模糊的。barrycarter,我仍在等待一个澄清的问题。@Simon是的,这是最直接的方法。但这其中的乐趣何在?:)@西蒙。我没有看到你的代码。我把这封信贴了出来,就在花环贴出他的答案的时候。我想删除它,但决定把它留在那里…@TomD:我没有发布我的代码-因为你抢先到了。所以我把你的答案投了更高的票-别管它,否则我的票就浪费了@西蒙,谢谢!最近投票很少(但我学到了很多):-)欢迎回来,巫师先生。假期过得愉快吗?你看到这个问题了吗?我想你会喜欢的;-)@谢谢,是的。没有,我没有。英雄联盟
Reap[Cases[data, {x_, y_} :> Sow[y, x], {2}], _, Prepend[#2, #1] &][[2]]
DeleteDuplicates /@ Flatten /@ GatherBy[Flatten[list, 1], First]
list = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, 
    bar3}}}
Gather[#][[All, 1]] & /@ Flatten /@ GatherBy[#, First] & @ 
 Flatten[list, 1]
l = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}};

SelectEquivalents[
   l
   ,
   MapLevel->2
   ,
   TagElement->(#[[1]]&)
   ,
   TransformElement->(#[[2]]&)
   ,
   TransformResults->(Join[{#1},#2]&)
]
UnsortedUnion @@@ #~Flatten~{2} &