Separate CSV to stucture array by a specified field

1 view (last 30 days)
Greetings!
I have a CSV file with the following contents:
"x", "y", "ZLEVEL"
15566.071598095354, 654.75138415898618, A
15730.023876579013, 660.38875580774038, A
15772.038140720921, 665.0524486236709, A
15861.67702561093, 669.09878141965692, B
15964.77015716501, 675.05706329613804, B
16054.020545106847, 683.1063847011992, B
16118.583970776759, 690.87616533615892, B
16231.136948002502, 695.99923622422557, C
16344.66294729244, 700.25827295850286, C
16400.372270382126, 705.20613829250306, C
16486.242397353868, 709.25627232144143, C
16564.589258300024, 715.96303745505884, C
16624.046537611983, 723.13271402537612, C
16752.728644676041, 727.80842778700935, C
16860.248868173338, 732.05753736629867, C
16906.759450074052, 736.81366143388732, C
I intent to create a 3 by 1 struct array with two fields XYData (matrix) and ZLEVEL (string), which holds the CSV data separated by ZLEVEL field and XYData matrix holds X and Y in its original CSV order.
Can you suggest me a nifty way (using built-in MATLAB functions) to do this please?
Thank you.

Accepted Answer

Walter Roberson
Walter Roberson on 19 Oct 2015
If you have R2014b or later you can use tableread() and then group the entries by ZLevel.
But that's because you asked for nifty, not for efficient.
  2 Comments
Andrey Kazak
Andrey Kazak on 19 Oct 2015
I was also thinking about using Table objects to solve this task. Can you share a snippet for grouping the entries of a table by ZLEVEL please?
Andrey Kazak
Andrey Kazak on 20 Oct 2015
Here is how one could achieve the goal. Let's assume that the table has name Main and we want to filter x and y values which have ZLEVEL equal to C:
Main{Main.ZLEVEL == 'C',{'x', 'y'}
And that's it! Very simple and convenient with help of Table object. As for data processing speed I found that even a large CSV file (100 MB) is being imported (at least on my average PC) fairly quickly.

Sign in to comment.

More Answers (1)

Guillaume
Guillaume on 19 Oct 2015
A table probably makes the reading of the file easier but I'm not sure it helps much after that. I don't think unstack is going to work for this.
It's still somewhat simple to do:
%read data with textscan
fid = fopen('somefile.txt', 'rt');
c = textscan(fid, '%f, %f, %s', 'HeaderLines', 1);
fclose(fid);
%or as a table
t = readtable('somefile.txt');
%partition the data,
%using a table here. replace t.x, t.y, t.ZLEVEL, by c{1}, c{2}, c{3} if using textscan
[levels, ~, pos] = unique(t.ZLEVEL); %get partitioning
xygrouped = accumarray(pos, 1:numel(pos), [], @(v) {[t.x(v), t.y(v)]}) %defer to accumarray to do the grouping
sarray = struct('XYData', xygrouped, 'ZLEVEL', levels) %and convert to struct
  2 Comments
Andrey Kazak
Andrey Kazak on 20 Oct 2015
Table objects worked very fine for my case.
1) convert ZLEVEL to categorical array:
Main.ZLEVEL = categorical(Main.ZLEVEL);
2) get categories of ZLEVEL
ZCats = categories(Main.ZLEVEL)
3) loop through ZCats and do what you need.
Guillaume
Guillaume on 20 Oct 2015
I thought your objective was to create a structure. Note that my example does use a table object.
Your step 1) and 2) are the same as my unique line.
Your step 3) is the same as my accumarray line.

Sign in to comment.

Categories

Find more on Cell Arrays in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!