Re: How to unflatten an array ?
- To: mathgroup at smc.vnet.net
- Subject: [mg112811] Re: How to unflatten an array ?
- From: Bob Hanlon <hanlonr at cox.net>
- Date: Fri, 1 Oct 2010 05:42:34 -0400 (EDT)
unflatten[arr : {{_, _, _} ..}] :=
SplitBy[{Most[#], Last[#]} & /@ arr, #[[1, 1]] &]
a1 = {{{{1, 0}, 1}, {{1, 1}, 1}, {{1, 2}, 3}}, {{{2, 0}, 5}, {{2, 1},
0}, {{2, 2}, 0}}, {{{3, 0}, 4}, {{3, 1}, 5}, {{3, 2},
2}}, {{{5, 0}, 1}, {{5, 1}, 3}, {{5, 2}, 2}}};
a2 = Flatten /@ Flatten[a1, 1];
a1 == unflatten@a2
True
Bob Hanlon
---- Valeri Astanoff <astanoff at gmail.com> wrote:
=============
Good day,
Suppose I have a flat array like this :
{{1, 0, 1}, {1, 1, 1}, {1, 2, 3}, {2, 0, 5}...
and I want to get back to this "unflattened" form :
{{{{1, 0}, 1}, {{1, 1}, 1}, {{1, 2}, 3}}, {{{2, 0}, 5}...
What is the most efficient way to do it ?
All I have found is this :
In[1]:= unflatten[arr : {{_, _, _} ..}] :=
Module[{f},
Scan[(f[#[[1]], #[[2]]] = #[[3]]) &, arr];
Table[{{x, y}, f[x, y]},
{x, arr[[All, 1]] // Union},
{y, arr[[All, 2]] // Union}]
];
In[2]:= a1 = {{{{1, 0}, 1}, {{1, 1}, 1}, {{1, 2}, 3}},
{{{2, 0}, 5}, {{2, 1}, 0}, {{2, 2}, 0}}, {{{3, 0}, 4},
{{3, 1}, 5}, {{3, 2}, 2}}, {{{5, 0}, 1}, {{5, 1}, 3},
{{5, 2}, 2}}};
In[3]:= a2 = Flatten /@ Flatten[a1, 1]
Out[3]= {{1, 0, 1}, {1, 1, 1}, {1, 2, 3}, {2, 0, 5},
{2, 1, 0}, {2, 2, 0}, {3, 0, 4}, {3, 1, 5}, {3, 2, 2},
{5, 0, 1}, {5, 1, 3}, {5, 2, 2}}
In[4]:= a3 = unflatten@a2
Out[4]= {{{{1, 0}, 1}, {{1, 1}, 1}, {{1, 2}, 3}},
{{{2, 0}, 5}, {{2, 1}, 0}, {{2, 2}, 0}}, {{{3, 0}, 4},
{{3, 1}, 5}, {{3, 2}, 2}}, {{{5, 0}, 1}, {{5, 1}, 3},
{{5, 2}, 2}}}
In[5]:= a1 == a3
Out[5]= True
Please help me to something faster for large arrays.
--
Valeri Astanoff