0
$\begingroup$

I use Matlab and generate data that I save in a structure in a MAT file. I want the results to be loaded into Mathematica, as several analysis and plots are best when done in the latter than in the former.

For example, in Matlab I generate the structure that contains different "a" and "b" fields, and "b" it's itself a structure that contains two fields "m" and "n":

Struct.a   = [1,2,3];                      %Vector data
Struct.b.m = [1,2,3;4,5,6];                %Matrix data
Struct.b.n = {'Name 1','Name 2','Name 3'}; %String cell array

I save this structure in a MAT file called "Struct.mat".

When I use the Import command in Mathematica 12:

P=Import["Struct.mat","MAT"];

I obtain P as the array of nested lookups:

{{{<|a->{{1.,2.,3.}},b->{{<|m->{{1.,2.,3.},{4.,5.,6.}},n->{{{Name 1},{Name 2},{Name 3}}}|>}}|>}}}

My question is: Is it possible to extract each field separately into another variable, without nesting lookups? For example, I use

M=Lookup[Lookup[P[[1, 1, 1]], "b"][[1, 1]], "m"]

to extract Struct.b.m into variable M; and I would like to use something like

M=Lookup[P,"b.m"]

PD. The data I obtain from Matlab has a lot of fields and nested fields, and those contain matrices with hundreds of rows and columns, string arrays and anonymous functions. This is a simplified example.

$\endgroup$
1
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Jun 21, 2021 at 22:48

1 Answer 1

1
$\begingroup$

Your P has reproduced your Structs as Associations but embedded them in some frustrating brackets.

Someone probably has a simple way to use Flatten to extract just the nested Associations.

Still likely worthwhile to work through what have so you can have an idea of what to do with it all.

Formatting it like the following may help you see what you have:

p = {{{<|
      a -> {{1., 2., 3.}},
      b -> {{<|
          m -> {
            {1., 2., 3.},
            {4., 5., 6.}
            },
          n -> {{{Name 1}, {Name 2}, {Name 3}}}
          |>}}
      |>}}};

Examining p:

Dimensions[p]
{1, 1, 1}

Taking the most embedded list:

p[[1, 1, 1]]

<|
 a -> {{1., 2., 3.}}, 
 b -> {{<|
     m -> {{1., 2., 3.}, {4., 5., 6.}}, 
     n -> {{{Name}, {2 Name}, {3 Name}}}|>}}|>

which starts looking more like a proper Association.

Assign a variable to the above:

p2 = p[[1, 1, 1]]

Now you can start to access the data:

p2[a]
{{1., 2., 3.}}

p2[b]
{{<|m -> {{1., 2., 3.}, {4., 5., 6.}}, 
    n -> {{{Name}, {2 Name}, {3 Name}}}|>}}

Hmmm....too many brackets on p2[b] so,

p2[b][[1, 1]]

<|m -> {{1., 2., 3.}, {4., 5., 6.}}, 
 n -> {{{Name}, {2 Name}, {3 Name}}}|>

Set a variable to the above just to make it easier to see:

p3 = p2[b][[1, 1]]

Then...

p3[m]
{{1., 2., 3.}, {4., 5., 6.}}

and

p3[10]
{{{Name}, {2 Name}, {3 Name}}}

First thoughts...

What you want to get to from your example:

p = <|
  a -> {{1., 2., 3.}},
  b -> <|
    m -> {{1., 2., 3.}, {4., 5., 6.}},
    n -> {{{Name}, {2 Name}, {3 Name}}}
    |>
  |>

Then you can access the data in a way analogous to how you would in a Struct:

p[a]
{{1., 2., 3.}}

p[b]
<|m -> {{1., 2., 3.}, {4., 5., 6.}}, 
 n -> {{{Name}, {2 Name}, {3 Name}}}|>

p[b][m]
{{1., 2., 3.}, {4., 5., 6.}}

p[b][10]
{{{Name}, {2 Name}, {3 Name}}}

More to come later...


So you can work something like the following into your code to import your Struct data:

p = {{{<|
      a -> {{1., 2., 3.}},
      b -> {{<|
          m -> {
            {1., 2., 3.},
            {4., 5., 6.}
            },
          n -> {{{Name 1}, {Name 2}, {Name 3}}}
          |>}}
      |>}}};

p = Flatten[p][[1]];
p[b] = Flatten[p[b]][[1]];
p

Which gives you:

<|
 a -> {{1.`, 2.`, 3.`}},
 b -> <|
   m -> {{1.`, 2.`, 3.`}, {4.`, 5.`, 6.`}},
   n -> {{{Name}, {2 Name}, {3 Name}}}|>|>

A well formed Association that you can readily access.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.