Using Mathematica Gather/Collect properly
How do I use Mathematica's Gather/Collect/Transpose functions to convert:
{ { {1, foo1}, {2, foo2}, {3, foo3} }, { {1, bar1}, {2, bar2}, {3, bar3} } }
to
{ {1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3} }
EDIT: Thanks! I was hoping there was a simple way, but I guess not!
Here is your list:
tst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}}
Here is one way:
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}}
EDIT
Here is a completely different version, just for fun:
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}}
EDIT 2
And here is yet another way, using linked lists and inner function to accumulate the results:
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}}
EDIT 3
Ok, for those who consider all of the above too complicated, here is a really simple rule - based solution:
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
If the "foo" and "bar" sublists are guaranteed to be aligned with one another (as they are in the example) and if you will consider using functions other than Gather
/ Collect
/ Transpose
, then MapThread
will suffice:
data={{{1,foo1},{2,foo2},{3,foo3}},{{1,bar1},{2,bar2},{3,bar3}}};
MapThread[{#1[[1]], #1[[2]], #2[[2]]}&, data]
result:
{{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}}
Pattern Matching
If the lists are not aligned, you could also use straight pattern matching and replacement (although I wouldn't recommend this approach for large lists):
data //.
{{h1___, {x_, foo__}, t1___}, {h2___, {x_, bar_}, t2___}} :>
{{h1, {x, foo, bar}, t1}, {h2, t2}} // First
Sow/Reap
A more efficient approach for unaligned lists uses Sow
and Reap
:
Reap[Cases[data, {x_, y_} :> Sow[y, x], {2}], _, Prepend[#2, #1] &][[2]]
链接地址: http://www.djcxy.com/p/35518.html
上一篇: 你将如何在Mathematica中做数据透视表功能?
下一篇: 使用Mathematica收集/正确收集