使用Mathematica收集/正确收集

我如何使用Mathematica的收集/收集/移调功能来转换:

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

{ {1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, 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

好的,对于那些认为上述过于复杂的人来说,这是一个非常简单的基于规则的解决方案:

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}}

也许更容易:

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

如果“foo”和“bar”子列表保证彼此对齐(如在示例中那样),并且如果您考虑使用除Gather / Collect / Transpose以外的功能,则MapThread就足够了:

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}}

模式匹配

如果列表不对齐,你也可以使用直接模式匹配和替换(尽管我不会推荐这种方法用于大型列表):

data //.
  {{h1___, {x_, foo__}, t1___}, {h2___, {x_, bar_}, t2___}} :>
  {{h1, {x, foo, bar}, t1}, {h2, t2}} // First

母猪/粒

对未对齐列表更有效的方法是使用SowReap

Reap[Cases[data, {x_, y_} :> Sow[y, x], {2}], _, Prepend[#2, #1] &][[2]]
链接地址: http://www.djcxy.com/p/35517.html

上一篇: Using Mathematica Gather/Collect properly

下一篇: Avoid repeated calls to Interpolation